All streams
Search
Write a publication
Pull to refresh
15
0

User

Send message
Например линзами можно удобно разбирать сложные JSON и XML, структура которых заранее не определена.

Это всё от лукавого, гораздо проще разбирать неизвестные JSON и XML обычной динамикой, а не линзами. Вы не замечаете как Хаскель подсовывает вам заведомо более сложный и неудобный инструмент для простейшей задачи?


Насколько я знаю в шарпе нет трансформеров монад и уж тем более нельзя писать штуки вроде таких:

Я ж написал — HKT нет. И не уверен что будет.
Ещё в F# нет зав и лин типов. Хочется, конечно, но довольно редко.


Я бы не сказал, что это "просто чуть менее удобно".

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


Например, Idris 2 Хаскелю насуёт по всем статьям, но что-то я не заметил чтобы хаскелисты бросили всё и на Идрис перешли массово) Хотя те же аргументы можно было применить и в обсуждении Haskell vs Idris.
Может кроме офигенных типов надо что-то ещё языку чтобы быть удобным?


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

Именно в этом мой поинт про семью и был. Вместо производства продукта, на Хаскеле я буду вынужден за 1 минуту нарисовать красивый хрустальный замок со всей мощью терката и оставшиеся 7ч59мин рабочего времени бороться с экосистемой. Я не люблю велосипеды, я не люблю кодить. Для меня это средство зарабатывания денег, поэтому чем меньше времени я трачу на решение задачи и доведения её до продакшна, тем больше времени у меня остаётся на личные дела.

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


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


Нет, хаскель хорош. Для обучения тому самому ФП, голову сломать, мышление поменять. Работать на нём — нет спасибо, у меня семья)

Удачно опробовал F# на проекте с Akka.Net, но дальше меня внедрение языка не ушло)
Я не хотел полумер и стал целенаправленно искать работу на F#.
Оказалось что ее достаточно даже в РФ)


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


А вот захантить таких людей надо обязательно в любой проект на C#, они подтянут уровень кода и команды.


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

Вот кстати очень редко вижу вакансии на F#, они вообще существуют в достаточном объеме?

Меня это немного смущало когда я на HH.ru не нашёл (2017) ни одной вакансии на F#, но резюме выложил. А звонки-то пошли! Из известных компаний где есть F# в РФ — Касперский и Microsoft. Звонили иногда из соображений — "F#? really?". Знающие работодатели хотели меня видеть у себя на C# позициях, но за бОльшие деньги. В итоге я нашёл себе работу на чистом F#, хотя ни одной F# вакансии в РФ на HH.ru на тот момент не было.

А может есть какой-то транслятор F# => C#?

dotPeek :) Но качество трансляции не очень!

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


F# открыл для меня другой мир. Мир где всё логично (как матан) и просто (как LISP), но тем не менее функционально (во всех смыслах) и практично. И денег ещё за это платят больше чем за страдания на C#.


Чем ещё хорош F# — это практичный язык, который не претендует на звание чистого, как Хаскель. В нём можно наговнокодить как в C#! И ещё он примазался к одной из крупшейних экосистем — .Net, что сразу снимает кучу головняка, интеграции, SDK, драйвера, БД, ОРМы и пр. Azure и Visual Studio идут в придачу (мало кто из ФП языков может похвастаться поддержкой таких IDE и облака).


Но есть и минусы, самый большой связан с C# :) Он (C#) настолько хорош, то убедить бизнесы переходить с него — прям таки адски сложная задача. Стоит ли? Вопрос не праздный, ответа у меня нет, я-то уже перешёл и не испытываю проблем с поиском работы.
А вот существующему бизнесу на C# вряд ли оправдано бросаться в пучины F#.

Сравните перечень поддерживаемых платформ у того же FPC и у C#)

Спору нет. Если вам ну очень нужна поддержка Solaris и PowerPC :)

Ничо что на C# пишут и под iOS, и под Android? Не говоря уж о линуксах?
Игровой движок Unity как бы намекает (mono).
Net Core опять же.


Бросайте уже эту "платформозависимую" чушь десятилетней давности повторять.

Для .net core просто во-первых нет столько программистов сколько нам надо, во-вторых Lazada которая почти полностью московским офисом вышла к нам писала на go и хотела продолжать это делать.

Был один стартап — Jet.com (тоже интернет магазин), который не то что на .net core, на F# бомбанул так сильно что его Walmart купил за 3 миллиарда $. На недостаток F# программистов не жалуются, пылесосят как могут со всего мира и сами взращивают.


У них изначально были облака, микросервисы и вот это вот всё. Представляете, .Net и микросервисы, и без Go. /sarcasm


Это я к тому что есть и другие пути кроме как "переписать всё на Go/Rust/Clojure".

И чтобы совсем никто не сомневался, в России на всякий случай запретили обсуждать итоги референдума в Крыму, да?

Никто ничего не запрещал.
Какой-то прокурор высказал личное мнение в статье журнала Коммерсант.


Главное не рефлексировать и ставить плюсики.

Поделюсь моей любимой картинкой с доклада о распределении рынка разработки:

А это из какого доклада?

Тогда пишется функция, где пишется return. Goto ни в одном проекте, слава богу, не встречал.

ОЧЕНЬ быстрые корутины на дотнете написаны с помощью goto


https://github.com/Hopac/Hopac/blob/6b4fe8e89e95aa9f2119e96f19d37cfe541e7715/Libs/Hopac.Core/Engine/Worker.cs#L129

Что за «проектирование типами»? Первый раз слышу термин.

Type Driven Development

Уточнение:


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

Скобки необязательны потому что "стрелка" правоассоциативна.


запись a -> b -> c -> d эквивалентна записи a -> (b -> (c -> (d)))


а вот ((a -> b) -> c) -> d означало бы СОВСЕМ другое.

Нигде, но тут и приложения как такового нет. Логика ж отсутствует, тут инфраструктурный код в основном.

Это не детский сад — это факт. Value Equality встречается эдак раз на сотню тысяч строк кода. То етьс на практике этой фичей практически никогда не пользуются. Есть огромные проекты в которых она не юзается ни разу.

У вас странный код. У меня Reference Equality встречается раз на сотню тысяч строк кода (в очень коварном месте где по-другому никак). И для него вполне хватает Object.ReferenceEquals, а всё остальное время сравнивать структурно.


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

Плохо что вы скатились в такую ахинею — утверждать что null safety не увеличивает качество кода. Все языки к этому идут (C#8 тоже), один Druu останется и будет корячиться с NullReferenceException


Ну и да, покажите мне тогда код на f# с protected. Сколько там строк будет?

Больше, да. Protected не реализован специально (чтобы не упрощать наследование реализации, а предпочитать композицию), если передирать 1 в 1, то придётся погемороиться с public / private.
Я вам сразу скажу чтобы вы не мучались в поисках контр-примеров — goto в F# тоже нет.


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

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

С-но вот:
https://pastebin.com/fcAXL6mD

Спасибо большое! Нет, без дураков, спасибо. Я не ожидал что Вы попытаетесь :)
Удивлён что был заюзан тот же Giraffe.


Пара комментариев:


  • Сам класс User конечно надо дополнить на Value Equality, что сразу добавит десяток строчек
  • Базовый абстракный Request не совсем корректен, т.к. он не запрещает добавление новых Request к этому множеству и компилятор вам не скажет что вы обработали не все виды запросов. Для этого типы-суммы и нужны (закрытые множества).
  • task — это монадка в F# для работы с тасками. Её прямой аналог async/await методы. F# просто позволяет монадический стиль и объявление где угодно, а не только в заголовке всего метода/функции.
  • .Match/.With вполне допускаю, видел такую реализацию в глубинах Akka.Net, но опять таки это только матчинг по ТИПАМ, без рекурсивного деконстракта, патернам листов, массивов, литералов и просто патернам. Аналог был бы switch/case (хотя в нём маловато всего, а рекурсивный патерн матчинг подъедет только в C#8)
  • фишку с применением Linq (from x in ...) я много раз видел, считаю синтаксис вырвиглазным, костыльным, сбивающим с толку, да и эти методы не реализуют итератор. В общем, мимо.
  • последний вопрос — это компилируется на C#?)

Added:
Хорошая попытка, но получили менее качественный код с чуть большим кол-вом строчек.
Чтобы получить похожее качество кода необходимо немного рефакторинга:


  • Обмазать всё хотя бы JetBrains аннотациями NotNull и иже с ними
  • Сделать Request sealed классом, чтобы нельзя было докинуть внешним пользователям кейсов, внутри него реализовать набор из вариантов. Это будет похоже на закрытое множество хотя бы. Каждый кейс кстати должен реализовывать ValueEquality.
  • Заменить Match With на switch case, всё равно switch case УЖЕ поддерживает тайп паттерны
  • Убрать неясно как работающий from x in CallAsync() select x. Не, серьёзно, за такой код надо сразу леща давать. Я ничерта не понял.
  • Добавить ValueEquality в User класс

Тогда будет уже ближе к передиранию 1 в 1, хоть и с мелкими недостатками.


Если Вы ещё не поняли, то передирание 1 в 1 без потери фич, но с повышением качества и уменьшением кол-ва кода ИЗ C# В F# возможно.
Обратное преобразование даже с потерей половины функционала (null check, value equality, exhaustive matching) увеличивает кодобазу.


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


P.S. И говорить что фича Х не нужна, поэтому я её реализовывать не буду — забудьте. Вас попросили сделать 1 в 1. Будьте любезны.

если дан код на F#, то вы можете его переписать на C# с минимальным разрастанием по объему.

Я Вам выше кинул челенж на переписывание сотки строчек. Пожалуйста, не проходите мимо.

На ваших слайдах 90% "экономии" — это фигурные скобки. То есть вообще не экономия. С-но если даже по строкам считать — там и получается ~30%, но если считать нормально, по зипу, то число резко упадет. Это, еще раз, если таковую экономию в принципе имеет смысл счиать (не имеет, конечно же).

Окей, перепишите мне 1 в 1 на С# пожалуйста эти 117 (включая пустые) строчек:
https://gist.github.com/Szer/fe0579aa7f5d780c3eecec3000c64447


IUserService реализовывать не надо.
Естественно с сохранением типизации реквестов/респонсов чтобы я потом мог наворачивать поверх типов сложную доменную логику по обработке ошибок или разных типов респонсов.

Как показывает практика, обычно в таких сравнениях берется няшный идиоматический код на F# и сравнивается с диким ужасом на C#. А если код на C# переписать из дикого ужаса в адекватном виде — то ВНЕЗАПНО разница падает на порядок.

Я ж слайды привел. Что там ужасного в С#? Обычный такой C# справа. И обычный такой F# слева (на самом деле не очень обычный, это просто калька кода из C#). Даже expression-bodied юзаются где можно

Information

Rating
Does not participate
Registered
Activity