Где C# перенял из F# (LINQ, async/await, expression-bodied methods/properties etc), уже выглядит более-менее одинаково.
А если начать использовать F# на полную (да хотя бы DU объявить на 3 строчки вместо портянки из наследуемых классов) там сокращение кода уже на порядок.
F# имеет некоторое количество синтаксического сахара, и на это все.
Так можно про любой язык сказать: Haskell это просто набор синтаксического сахара над Асмом (или Лиспом). Это ж всё Тьюринг полные языки и при должном старании и времени все абстракции одного могут быть выражены в другом.
Называйте как хотите, код на F# в разы меньше кода на C#. Благодаря ли синтаксическому сахару, ML синтаксису или каким-то абстракциям (экспрешны, алгебраические типы, карирование и всё такое прочее).
Странно что у вас такие сомнения по этому заявлению.
Переход на более высокий уровень абстракции убирает часть кода (потому что мы, очевидно, от него абстрагируемся).
Переход с Assembly на C++
Переход с C++ на Хаскель
Переход с C# на F# не такой резкий чтобы прям на порядок уменьшить, но раза в 2 вполне. Я говорю за себя точно (был опыт переписывания с С# на F# одного крупного проектов и несколько мелких), так же есть опыт других людей.
Этот опыт переписывания не такой обширный потому что в последствии понимаешь что проще сразу на F# писать чем потом переписывать.
Нет, самое ближайшее (и оно, конечно, есть в хаскеле) это частичный деконстракт, и выведение типа рекорда для аргумента функции чтобы сразу обращаться к полям
1) Вы пытаетесь схитрить, сделав вид что в F# не нужна функция, конструирующая Employee
let newEmployee id name email hasAccessToSomething hasAccessToSomethingElse =
{ Id = id
Name = name
Email = email
HasAccessToSomething = hasAccessToSomething
HasAccessToSomethingElse = hasAccessToSomethingElse }
Это лишь показывает твой невысокий уровень знания F#.
Да, эта функция не нужна.
Если ты так писал (или пишешь) неудивительно что у тебя так горит с языка.
F# практически ни где в реальной жизни не используется, соответственно и отладчик не нужен
А ещё можно зажмуриться и повторять себе — F# не существует. Поможет.
Плюс в C# есть такая полезная опция, как реверсинг на лету и go-to-definition в библиотечный код, который так же можно дебажить. Программист на F# нервно курит в сторонке или рассказывает что дебагер нинужен
Декомпиляторов из IL в F# нет, это правда. Или я таких не знаю.
Нервно не курю, дебагером пользуюсь.
Не надо свой опыт 6-ти летней давности втирать людям как актуальный.
Linter — fantomas
Тулинг — обычный Net Core SDK (dotnet build и погнали). F# компилятор нынче в него включён, ничего ставить не надо, если неткор стоит.
Про отсутствие доков, это конечно же прогон. В Hopac дока просто гигантская. Giraffe (на мой взгляд самый перспективный веб фреймворк, т.к. поверх asp.net core) прекрасно документирован.
Если что, pawlo16 известный в комьюнити F# хейтер. К его словам надо с пудом соли относиться. Ходит по всем F# статьям на хабре и рассказывает как он когда-то не осилил, а Go эт просто космос :)
Но, думается, некоторая «избыточность» кода C# в сравнении с F# картины ничуть не портит. А вот будет ли нетривиальная бизнес-логика столь же «читаема» в коде F#? Как ни крути, в продакшн не обойтись без сонма классов, без многоуровневой иерархии объектов в домене приложения…
Потому — соглашусь с апелляцией к «боевому» коду. Мне интересно было бы почитать разбор мало-мальски сложных проектов на F#, решающих задачи «реального» мира.
Обойтись без сонма классов очень даже можно. Отказываться от них полностью бессмысленно, они полезны. Но строчить классы для ВСЕГО — так же глупо, как всё засовывать в чистые функции.
Во втором примере вообще желание чего-то странного, я даже толком мысли не понял.
Это пример того что C# это всё же язык про стейтменты. Нельзя куда угодно засунуть какой хочешь экспрешн.
В if-стейтменте можно делать что хочешь (явные блоки { }), но это не выражение, оно ничего не возвращает (поэтому проверки типов у разных веток if нет и быть не может).
В ?-операторе ничего делать нельзя (явные блоки { } не поставишь), но оно обязано возвращать, а т.к. C# не умеет в unit/Void, то писать в ?-операторе unit/Void операции нельзя.
Здесь компилятор F# идёт вверх по коду и ищет первый подходящий объявленный record (в нём обязаны совпадать все поля). И неявно выводит тип Employee у идентификатора employee.
Оно может поломаться если между объявлением type Employee =
и созданием let employee = ...
объявить другой рекорд с ровно теми же полями. Тогда компилятор неявно выведет этот самый другой тип у этой же переменной.
Это конечно поломает код (строгая типизация жеж) и вы сразу заметите ошибку в IDE, так что проблем нет. Если такой шадоуинг типов не ломает билд, то значит предыдщий рекорд ничего полезного не делал :)
Тем не менее, это вполне работающая практика. В golang так делают, в некоторых проектах в nodejs тоже принят такой стиль обработки ошибок. И этот подход можно использовать почти везде, даже в языках, где ООП нет вообще.
В Go не от хорошей жизни так. Как только в языке появляются человеческие типы-суммы об этом ужасе надо забывать. Зачем брать в пример неудачные реализации?
Если просто 1 в 1 переписать на F# (прям в C# стиле, со всеми этими интерфейсами, наследованием и пр) уже будет больше 30%
Скрины слайдов:
https://imgur.com/a/Ghxapve
Где C# перенял из F# (LINQ, async/await, expression-bodied methods/properties etc), уже выглядит более-менее одинаково.
А если начать использовать F# на полную (да хотя бы DU объявить на 3 строчки вместо портянки из наследуемых классов) там сокращение кода уже на порядок.
Так можно про любой язык сказать: Haskell это просто набор синтаксического сахара над Асмом (или Лиспом). Это ж всё Тьюринг полные языки и при должном старании и времени все абстракции одного могут быть выражены в другом.
Называйте как хотите, код на F# в разы меньше кода на C#. Благодаря ли синтаксическому сахару, ML синтаксису или каким-то абстракциям (экспрешны, алгебраические типы, карирование и всё такое прочее).
Странно что у вас такие сомнения по этому заявлению.
Переход на более высокий уровень абстракции убирает часть кода (потому что мы, очевидно, от него абстрагируемся).
Переход с Assembly на C++
Переход с C++ на Хаскель
Переход с C# на F# не такой резкий чтобы прям на порядок уменьшить, но раза в 2 вполне. Я говорю за себя точно (был опыт переписывания с С# на F# одного крупного проектов и несколько мелких), так же есть опыт других людей.
Этот опыт переписывания не такой обширный потому что в последствии понимаешь что проще сразу на F# писать чем потом переписывать.
Нет, самое ближайшее (и оно, конечно, есть в хаскеле) это частичный деконстракт, и выведение типа рекорда для аргумента функции чтобы сразу обращаться к полям

Последнюю строчку написать в F# нельзя:

Зато теперь похоже на правду.
Не смущает что статистика устарела на 4 года?..
Чукча не читатель, понимаю.
Это лишь показывает твой невысокий уровень знания F#.
Да, эта функция не нужна.
Если ты так писал (или пишешь) неудивительно что у тебя так горит с языка.
Эту чушь от тебя я уже опровергал в какой-то из прошлых статей про F#, где ты рассказывал то же самое.
Даже ссылку оставлю, освежить тебе память.
А ещё можно зажмуриться и повторять себе — F# не существует. Поможет.
Декомпиляторов из IL в F# нет, это правда. Или я таких не знаю.
Нервно не курю, дебагером пользуюсь.
Не надо свой опыт 6-ти летней давности втирать людям как актуальный.
Если что, pawlo16 известный в комьюнити F# хейтер. К его словам надо с пудом соли относиться. Ходит по всем F# статьям на хабре и рассказывает как он когда-то не осилил, а Go эт просто космос :)
Обойтись без сонма классов очень даже можно. Отказываться от них полностью бессмысленно, они полезны. Но строчить классы для ВСЕГО — так же глупо, как всё засовывать в чистые функции.
Про избыточность C# по сравнению с F# неплохо сказано в свежих докладах Антона Молдована и Вагифа Абилова:
https://www.youtube.com/watch?v=4eXthLWzYrk
https://www.youtube.com/watch?v=4x9slVi_RBo
Сам пишу прод на F#, экономит тонну времени.
И тут можно наступить на родовую болезнь C# — отсутвие unit/Void.
Перегрузить Ternvoke для работы с Func<> не получится (вход можно, а выход — нет).
Пример из продакшна. В пайплайнах есть функция
tee
, которая просто делает сайдэффект над передаваемым аргументом и возвращает его же.F#:
C# :
Предположим у нас есть функция
saveToDb: 'a -> bool
(принимает что-то, сохраняет в бд, возвращает успешно или нет)F# пережовывает что угодно:
C# уже не очень:
Added:
А было бы неплохо объявить на C# так:
Но увы
Все пропозалы — это требования того, чего нет в спецификации. Если этого не требовать, язык перестанет развиваться.
Все кто пишут пропозалы — странные?
Это пример того что C# это всё же язык про стейтменты. Нельзя куда угодно засунуть какой хочешь экспрешн.
В if-стейтменте можно делать что хочешь (явные блоки { }), но это не выражение, оно ничего не возвращает (поэтому проверки типов у разных веток if нет и быть не может).
В ?-операторе ничего делать нельзя (явные блоки { } не поставишь), но оно обязано возвращать, а т.к. C# не умеет в unit/Void, то писать в ?-операторе unit/Void операции нельзя.
Здесь компилятор F# идёт вверх по коду и ищет первый подходящий объявленный record (в нём обязаны совпадать все поля). И неявно выводит тип
Employee
у идентификатораemployee
.Оно может поломаться если между объявлением
type Employee =
и созданием
let employee = ...
объявить другой рекорд с ровно теми же полями. Тогда компилятор неявно выведет этот самый другой тип у этой же переменной.
Это конечно поломает код (строгая типизация жеж) и вы сразу заметите ошибку в IDE, так что проблем нет. Если такой шадоуинг типов не ломает билд, то значит предыдщий рекорд ничего полезного не делал :)
Добавим чутка скобочек и вот он LISP!
Ну такое. Это не компилируется:
Такое почему-то тоже
Так что тернарный оператор в C# конечно уступает expression-based if из F#
deleted
Бабка на двое сказала. Только пропозал есть с мая. До сих пор в том же состоянии.
В Go не от хорошей жизни так. Как только в языке появляются человеческие типы-суммы об этом ужасе надо забывать. Зачем брать в пример неудачные реализации?
Я UI не занимаюсь вообще, поэтому это не ко мне :) Знаю что его на F# делают. Ссылки в каментах.
А если вообще — да, плюсы от использования F# могут перекрыть затраты на поиск разрабов F# / перевоспитание C#-истов. Но не для малого бизнеса имхо.