Как стать автором
Обновить
41
0
Роман Лиман @kagetoki

F#/C# developer

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

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


Я же уже показывал, как такой код транслируется почти без потерь по размеру. Поскольку объявлений типов там нет, а есть только логика, то перевод будет с оверхедом ~15% (можете сами перевести и проверить), из них больше половины — скобки, то есть указанный вами код на c# по факту записывается с эффективным оверхедом около ~5%, примерно 128 строк вместо 121 (если брать второй файл, например). Как видно, ни о каком "f# позволяет писать на порядок меньше кода" говорить нельзя, экономия в 7 строчек из 128 — это детский сад.

Вы первый файл смотрели? Там ТОЛЬКО объявления типов. Кстати, у вас с каждым следующим комментом заявленный оверхед магически уменьшается. Сначала было 30% с учетом скобок и 15% без, потом 15% с учетом скобок и 5% без.
Да, киньте в меня плз ссылкой, где вы показывали это, сорян, если я в танке сижу и пропустил.


Мне не нравится заставлять/предлагать вам переписать на C# то, что у меня есть на F#, но я не вижу другого выхода, раз вы кидаетесь громкими утверждениями и с потолка берете 121 строку и 5%.
Если таки возьметесь за переписывание этих двух файлов — давайте облегчим задачу: необязательно транслировать 1 в 1. Просто реализуйте ту же логику: классическая змейка + перки на атаку и скорость с кулдауном. Потом сравним надежность, лаконичность и читаемость.

Рассуждения о том, что Value Equality не нужно на практике (почитайте что ли про DDD и Value Objects vs Entities) — это детский сад. Оно не нужно такой ценой, оторой достается на C#, но нахаляву этому будут рады все.


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


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

Нет разницы. Смысл в том что это не относится к клиентскому коду.

Есть разница, и я сразу написал, в чем она. Раз уж меряем код — давайте мерять честно.


При желании можно добавить, поправив реализацию Match/With и добавив кодировку кейзов, например, параметрами генерика. В клиентский код добавится по паре строк на тип примерно, но это все по факту неинтересно.

Довайте добавим, если мы хотим полный эквивалент.


И точная оценка в 30% — это не чудесное совпадение

Это не точная оценка, много чего опущено.


Это уже тоже к делу не относится, речь же о переписывании конкретного кода.

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


Конечно, если у вас весь код — это объявление кучи discriminated unions, то тут получится выгадать ~30%

Там объявлено 2 юниона. Это 11 строк из 117, которые там есть. Если вы думаете, что приведенный пример это специально надроченный семпл, чтобы показать максимум лаконичности, вы глубоко заблуждаетесь.


И мой поинт все еще остается в силе — в F# меньше кода (даже по вашим приуменшенным оценкам), и код надежней.


Скоро в c# добавят сахарок для рекордов и нормальный паттерн-матчинг (и nullable типы нормальные) и, с-но, все, до свидания, основные преимущества f# будут покрыты.

Nullable типы будут не нормальные. На уровне рефлекшна никакой разницы не будет между string * string?, так что это уже хуже, чем Option<'T>.
Record types — посмотрим, добавят ли подобие with синтаксиса.


f# просто не предоставляет какие-либо средства, которые могли бы серьезно помочь в сокращении кода. Ну нету там таких средств. discriminated unions можно проще объявлять, деконструкцию в паттернах быстрее делать и экономить за счет сложных дслей в computational expressions — список закончился.

Вы даже тут уже сами себе противоречите. Хотите преуменьшить возможности F# изо всех сил, но даже у вас набрался список из 3 серьезных пунктов, хотя говорите, что средств нету. Клоунада.

match & with это не библиотечные функции, это языковая конструкция, так же как и if/else или switch case в сишарпе. И работает этот матч не только с заданными типами, а вообще с чем угодно. Так что справедливо было либо переписать на if else / switch case либо указать реализацию ваших функций Match & With. Кстати, в них будет пусть и небольшой, но оверхед, но это мелочи.
Exhaustive check не особо нужная фича? С чего бы? Это ворнинг нахаляву (а при warning as errors ошибка компиляции) вместо юнит теста. Нихера себе ненужная фича.


Да, а еще у вас нет null safety.


Кстати, будет ли работать ваш from-select, ведь эти методы возвращают не IEnumerable?


В итоге даже в таком примитивном примере, где нет ни многопоточности, ни сложной смены состояний, ничего вообще интересного, мы получили больше строк кода (кстати, не забудьте либо переписать на if else / switch либо добавить реализацию функции Match+With), а решение менее надежное. Что и требовалось доказать.

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


А то, что F# ничего кроме сахара не имеет — ну, называйте это как угодно. Сахар, кодогенерация — не важно. Кучу бойлерплейта убирает, и головной боли меньше. Скорость разработки растет, стабильность кода тоже. Что еще нужно?

VS Code уже давно полноценная ide

Все с вами ясно


Спикеры на конфах, активисты сообщества в блогах и чатах, рассказывая про F#, показывают именно ionide. Видимо они не в курсе, что он дерьмово работает.

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


Там те же проблемы — периодически всё ломается и не работает. Сообщения об ошибках не пустые, да. Но от этого они не на много более информативные.

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


Ваша с юзером Сзер риторика соответствует моим представлениям о типичном фанбое F# — хамоватом студенте неудачнике.

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


Если кому-то кажется, что все вокруг идиоты, варианта два: либо он невероятный гений, либо он сам идиот.
Ну, может быть, вы и правда гений. История нас рассудит.

Кого и зачем вы пытаетесь обмануть? VS Code это текстовый редактор, а Ionide это лишь плагин к нему. И о боже мой он дерьмово работает на больших проектах, и временами выдает дурацкие ошибки.
Где тут промышленный тулинг и IDE?

Однако, вы ничего не сказали про Visual Studio & Rider. Когда вы уже успокоитесь и перестанете строчить свои поверхностные субъективные желчные комменты? Ведете себя так, словно F# материализовался и лично насрал вам в миску.
Потому что вы видите сопоставление имени поля и имени переменной, которую собираетесь туда присвоить. При нормальном нейминге шанс ошибиться ниже. Это не значит, что он нулевой, но он ниже
let name = "name"
let email = "email"
let has1 = true
let has2 = false
let emp1 = newEmployee id name email has1 has2
let emp2 = newEmployee id email name has2 has1

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

Ну вы сейчас явно выдумываете, первый вариант объективно лучше.

Ну вы сейчас явно выдумываете, первый вариант объективно хуже.

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


Может быть, дело не в языке?

Ага, ведь на каждом языке/фреймворке стоит правдивый лейбл "Я принесу вашему бизнесу 273 доллара за 2 недели". C# занял свою нишу, на нем написана куча проектов и программистов на нем гораздо больше на рынке. Внедрение новой технологии это всегда риск, и каждый бизнес сам решает, насколько он охотно идет на это. Посмотрите на обилие легаси проектов с древними технологиями и ужасным кодом — для бизнеса было бы просто чудесно по щелчку пальцев превратить этот код в хороший: и фичи быстрее делаться будут, и багов будет меньше, и текучка кадров упадет, и басфактор тоже снизится. Но бросить все и написать с нуля — это риск и гарантированный простой продукта. Переписать все на новый язык с новой парадигмой — это еще больший риск. А потом же обязательно стоит учесть момент с количеством кадров — сейчас мы перепишем, а нанимать кого будем?


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

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

Боже, как же мы без вас? Кто придет в статью про F# и расскажет, какое он дерьмо, кто придет на хабр и откроет нам глаза, что хабр сделан идиотами? Потеря.


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

Лень отвечать, но не лень приходить под каждую статью про F# и рассказывать, какой это дерьмовый и никому не нужный язык.

Интересно, как вы себе представляете ссылку на реальный проект? Что кто-то откроет свои исходники, сохраняя при этом легаси, ради того, чтобы Паша с хабра успокоился?

Когда мне говорят, например, что после перехода на F#


  • кол-во кода сократилось на 60%
  • производительность в таких-то сервисах упала на 4-7%
  • кол-во аллокаций выросло на 15%
  • время реализации новых фич упало с 1 месяца до 1-2 недель, да плюс кол-во багов уменьшилось


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



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


  • Библиотек у F# нет? Giraffe, Hopac, Rezoom.SQL, FsharpLu.Json Json/Xml/Csv type providers и так далее. С чего это они маргинальные? Если проект поддерживает 1-2 человека, это не значит, что он плох. Может быть, просто язык настолько хорош, что вам не нужна армия мейнтейнеров? А может быть, библиотека не так уж сложна? Или автор дьявольски умен?
  • Тулинг отвратительный? Это ложь. Тулинг хуже, чем у C#, но не настолько, чтобы скулить об этом под каждой статьей и уж тем более не настолько, чтобы заниматься промышленной разработкой было нерентабельно.
  • Все либы написаны под сишарп? Это ложь, ссылки выше.
  • F# в эти либы можно только сбоку воткнуть? С чего бы? F# умеет ООП не хуже C#, да и ООП вообще тут не при чем, используй себе и ОРМ, и автомаппер, и ASP.NET, если не хочешь жираф, суаве или сатурн. Код бизнес-логики это вообще не затрагивает.
    Сборка проектов маргинальными утилитами? Это вообще блин о чем? Проекты собираются и классическими средствами ровно так же, как и C#. К слову, на нашем C# проекте используется FAKE.
  • Функциональные структуры данных не такие эффективные? Да у нас тут преждевременный оптимизатор в треде. В C# коде чаще всего фигурируют IEnumerable<> & List<T>. Самая частая операция с ними — foreach. Давайте, расскажите мне, как форыч по листу в миллион раз эффективней форыча по связному списку.
    Далее, поиск по функциональной мапе медленнее, чем по хеш таблице, да. Только кто заметит эту разницу на словаре, в котором 10-20 элементов?
    А вот там, где действительно нужна высокая скорость работы, можно использовать императивные коллекции, никто не мешает это делать. Получается, в F# у вас есть выбор между функциональными и императивными коллекциями, а в C# нет. Ну, если не считать Collections.Immutable, который все ругают.
  • Неоправданный рост когнитивной нагрузки при чтении ФП кода? Это чистая субъективщина, не подкрепленная вообще ничем. Когнитивная нагрузка при чтении ваших бездоказательных утверждений для меня выше, чем при чтении качественного ФП кода.
  • ФП код невозможно дебажить? Хорошо, что я не знал этого, когда дебажил ФП код. Слава богу, приходится его дебажить гораздо реже, чем ООП, иначе невозможное пришлось бы творить слишком часто.

F# имеет аттрибут [<CLIMutable>]. Он позволяет мутацию, но не из вашего F# кода.

Ну вы же понимаете, что это непрактично для продакшна? А если мне нужно другое количество аргументов? А если это не Func, a Action?
Сравните теперь с каррингом в F#, где он нативный, и делать не надо ничего вообще.


let inline add x y z = x + y + z
let add5 = add 5
let add5then7 = add5 7

Хорошо, пример с if/else неудачный, черт с ним.
Меня тут несколько раз уже носом ткнули в это, вы не первый. Как насчет всего остального, что есть в статье?


Далее. readonly? Хорошо, но кода надо написать все еще гораздо больше, чем в F#.
И это важно, потому что это влияет на решение разработчика о том, как он будет писать код. Все предпочитают двигаться по пути наименьшего сопротивления, все хотят писать меньше кода для решения одной и той же задачи.
У разработчика есть выбор:
1) Написать обычную изменяемую структуру, которая всем понятна и является дефакто стандартным решением этой задачи, набрав X символов
2) Написать неизменяемую структуру, набрав 3X символов, объяснять на код ревью, почему было принято такое странное решение, писать больше кода каждый раз, когда хочешь поменять 1-2 поля в ней, и, скорее всего, научить JsonConvert парсить ее, потому что дефолтного конструктора нет.


Кто в здравом уме выберет второй вариант?
Не забывайте, написать на C# неизменяемую структуру на принцип, чтобы доказать кому-то что-то, это совсем не то же самое, что писать так каждый день на работе.
То же самое относится к вашему "учите матчасть". Так сделать можно, но никто так делать не будет.


Что насчет неизменяемых коллекций в C#? Да, есть Collections.Immutable, но их все ругают за тормознутость, я ни в одном проекте не видел их использование.


Кстати, Equality & Comparison все еще надо самостоятельно реализовывать.


Покажите, пожалуйста, как выглядит каррирование на C#. Я честно не знаю.

Мне больше всего понравился этот сайт.

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


А вообще в вашем утверждении можно поменять "функциональной" на "оопэшной", и суть не изменится — субъективщина без аргументов.

Информация

В рейтинге
Не участвует
Откуда
Сингапур, Сингапур, Сингапур
Зарегистрирован
Активность