Полтора года назад я писал статью про сообщество F# разработчиков. Мне казалось странным, что люди, у которых есть столько возможностей для карьерного развития, бросают гигантские силы на изучение странного не особо кому нужного языка.
Но внутри я встретил самое дружелюбное и живое сообщество разработчиков из всех, с кем общался. Пацаны приводили много логичных доводов почему они выбрали F#, но у меня все равно осталось впечатление, что они выбирают не умом, а сердцем. Очень необычная фигня для такой прагматичной индустрии.
Спустя полтора года после статьи я позвал Романа Мельникова на подкаст и обсудил, как все обстоит сейчас.
Несколько цитат Романа изнутри:
Для чего начал собирать сообщество
F# сообщество делалось, чтобы вывести язык из маргинализированной зоны и сделать его плюс-минус энтерпрайзным стандартом, чтобы хоть где-то получалось находить работу. И мы хорошо продвинулось. Раньше F# вообще не вспоминали на Хабре, а сейчас я постоянно его где-то вижу.
В 2014 году я сделал бизнес — заказную разработку — и мечтал собрать команду, которая писала бы только на F#. Это была просто блажь — мне хотелось стать тем работодателем, который пишет на F#.
Но не получилось, я закрыл это дело. Зато начал расти чат в телеграм и, и мы решили собирать вокруг него сообщество, примерно в 2016 году. Я планировал возродить старую идею, собрать комьюнити, чтобы у меня была куча разработчиков, которые хотят писать на F# и стать титульной компанией для этого языка. Например, есть компания Jet.com. Это e-commerce, и там сотни разработчиков пишут только на F#. Потом их купил Wallmart, и это крутой кейс. Мне хотелось стать таким русским Jet.com
Но и это тоже не получилось. Зато я получил кучу знаний, в сообщество приходят очень умные ребята. Был даже ученый-физик, который использовал F# в моделировании, и у него отлично получалось. Язык реально позволял это делать. Я пообщался с кучей умных ребят, и это как минимум подняло мой уровень. Через какое-то время меня просто стали звать на работу туда, где был нужен F#.
Почему выбрал F#
У меня была такая задача — я хотел писать быстро, красиво и много — а на F# это можно. Для бизнеса тоже есть ценность, потому что обычно ему приходится нанимать условно двух разработчиков для того, с чем мог бы справиться один на F#
Я понимаю, что все это спорная вещь, и люди будут говорить — да ну нахер ваш F#. Можно по разному относиться, но один хороший F# разработчик реально может заменить двух средних сишарперов.
Если у тебя есть поле для экспериментов, например совсем свежий стартап, то можно взять неплохих сишарперов, научить их F#. Адекватным .Net разработчикам, которые знают стандартную библиотеку — им пофигу, пишешь ты на C# или F#. Когда ты .Net разработчик, ты знаешь .Net, а C# просто в придачу, по умолчанию. Поэтому легко вкатишься и F#. Сначала на F# ты можешь даже писать так же как на C#, и от этого уже будет профит, потому ты будешь писать меньше. Если человек видит, что язык помогает сократить ему 15% кода — он возьмет и сократит. Меньше кода — меньше багов.
Конечно, как менеджер я бы наверное не менял парадигму, если у меня уже есть 26 C# разработчиков, и мне нужно в срок сдать проект. Но если бы я начинал проект с нуля — F# идеально заходит.
О непопулярности языка
У F# никогда не будет большинства. Но знание F# и особенно желание писать на нем, понимание его плюсов — это отличнейший флаг при выборе программистов. Я сразу понимаю, что человек шарит. Он понимает в .Net, а не только C#, он понимает, как можно делать по другому.
F# позиционировался как язык для обработчиков данных, для data science. Хотя это хороший язык и для фронта, и для веб-разработки. Той же жертвой, например, пал Rust — все говорят, это язык для системой разработки, хотя на нем очень хорошо писать веб-приложения и бэкенды. Он отлично подходит для WebAssembly.
Про сравнения с C#
Новые фичи, которые появляются в C#, идут только на пользу F#. Например, движения C# 9 с кучей атрибутов против null — у меня от них взрывается мозг, когда я читаю, как этим пользоваться. А в F# по умолчанию не может быть null рефов, и ты не пишешь ничего для этого. Поэтому когда они портят C# — для это F# лучше. F# становится для C# своего рода Котлином для Джавы.
Как C# разработчик я радуюсь новым фичам в языке. Но C# сильно вдохновляется F# — паттерн матчинг, рекорды — это все из него пришло. Сейчас нам становится только легче пересаживать заядлых сишапрперов на F#.
Про дружелюбность сообщества
Я сразу хотел построить комьюнити, которое будет добрым. Первые три года все, абсолютно все, говорили, как у нас уютно. Я понимал, что если ты топишь за язык, который сейчас не очень популярен, и если ты будешь всех посылать, люди которые интересуются языком, так к тебе и не придут.
В все, кто был в комьюнити с самого начала, помогали поддерживать дружелюбный фон. В итоге он распространился на тысячу человек. Сейчас управлением занимаются 15 человек, причем никто не раздавал им функции специально.
Это комьюнити не вызывает ассоциаций со стереотипными ФП-шниками. Кажется, что мы сильно другие ребята, не такие как хаскелисты и остальные. Даже не такие как дотнетчики. Зайди в фиолетовый чат .Net ru — и все, капец, сплошные срачи.
Наше комьюнити скорее выработало подход, что мы не ФП-разработчики — мы прагматичные разработчики. Когда надо, мы используем классы, когда можно — фп-подходы. И это не только локальная тема. Дон “святой наш” Сайм говорил, что F# — это язык не функциональный, а functional first. Потому что где надо, ты используешь ФП, а где не надо — используешь ООП, потому что это тоже нормальная разумная практика там.
ООП головного мозга должно умереть, так же как и ФП головного мозга должно умереть.
Я не супер фанат Дона Сайма, и его святость — это конечно шутка. Он просто хороший чувак, у которого есть видение языка, и он его транслирует. Комьюнити языка движется скорее другими людьми. К Дону есть претензии, когда он закрывает некоторые проблемы by design. Он не очень любит выезжать, но мы как комьюнити сформировали рынок потребностей. И, например, недавно он приезжал в Украину. Там тоже очень много наших ребят. И это был первый раз, когда он приезжал говорить с русскоязычными разработчиками.
0x1000000
Думаю, что основная причина отсутствия популярности у F# это, как ни странно, .Net, ведь любая программа на F# будет обладать примерно схожими эксплуатационными свойствами, как и такая-же программа на C#: она будет работать (плюс/минус) с той же скоростью, потреблять приблизительно столько же памяти и количество платформ на которых эти программы можно запустить будет точно таким же. Как результат, при выборе языка будут использованы такие критерии как:
capslocky
YChebotaev
Только эти два критерия относятся не к языку, а к программисту. Программист пишет больше или меньше кода, и баги допускает тоже программист.
AnthonyMikh
Именно поэтому на программах на C++ и на Java одинаковое количество багов </sarcasm>
YChebotaev
Вы путаете баги и дефекты. Да, время реализации фичи зависит от количества дефектов в программе, и язык может помогать или нет в их выявлении. Но количество багов, которые найдены на тестировании зависит только от программиста.
Doomsday_nxt
по этой же причине языки без строгой статической типизации — приводят к большему количеству трудноотлавлиемых багов (само собой речь не о двух обсуждаемых языках)
YChebotaev
Если бы ваши слова были правдой, то программисты сделали бы динамические проверки типов в языках без статической типизации. Но практика показывает, что программисты вообще никак не защищаются и ничего не делают ради этого.
И в любой опенсорсный язык можно делать коммиты, почему-то никто не расширяет языки системой типов. Единственное исключение — JavaScript, но для него делать компиляторы вообще национальный спорт.
Doomsday_nxt
Коммиты вы сделать не сможете… А вот МР — можете… Которые отклонят в большинстве случаев… Есть опыт… Вы слишком идеализируете опенсурс…
YChebotaev
Ну так MR — это запрос на включение коммитов. Если бы это было реально нужно, то не отклонили бы и было бы очень много желающих расширить языки системами типов. Того что этого нет однозначно свидетельствует, что важность системы типов сильно преувеличена.
Doomsday_nxt
я имею ввиду — в рабочую ветку вы ничего незакомитите. МР вы создать можете. Но судя по тому что я наблюдаю — КРАЙНЕ РЕДКО принимают МР не от «своих»…
YChebotaev
Вы можете сделать форк и если ваш форк с системой типов был бы кому-нибудь нужен он стал бы более популярен чем оригинал.
Вернемся к обсуждению по-существу?
0xd34df00d
Наличие типизированных языков свидетельствует, что важность систем типов сильно недооценена.
Отсутствие MR'ов в условный питон всего лишь означает, что тем, кто пишет на питоне, по тем или иным причинам это не нужно (а когда становится нужно, например, они могут перестать писать на питоне и мигрировать на другой язык).
0xd34df00d
Потому что
YChebotaev
1. В мире полно талантливых людей, которе будут рады решить любую нетривиальную задачу.
2. Вот именно. Статическая типизация — личное предпочтение конкретного программиста, и не влияет на продуктивность.
0xd34df00d
Неплохо, чтобы задача при этом вообще имела решение (иногда это Тьюринг запрещает, скажем), и чтобы, более того, эта задача имела смысл. Зачем из условного питона делать условный хаскель, несовместимый с уже имеющимся питоном, если можно просто взять хаскель?
Не понял связи, ну да ладно.
Что значит «не влияет»? То есть, если я возьму нетипизированный язык, то моя продуктивность не упадёт? Или существует человек, у которого на нетипизированном языке такая же производительность, как у меня на типизированном?
А тесты, кстати, влияют на продуктивность? А грамотная архитектура, солиды-киссы всякие, не знаю?
YChebotaev
Что именно запрещает Тьюринг?
Думаю, да. Есть типизированный диалект Python-а — Boo. Попробуйте сравнить.
Я думаю, что это, опять-же индивидуально для каждого работает. То есть, глобально все эти вещи программистам не нужны. Но некоторые программисты испытывают сложности с тем или иным кодом и им требуются дополнительные условия. То есть, это как протез. Нет ничего плохого в том, чтобы им пользоваться, но нельзя утверждать, что «протез увеличивает производительность для всех и каждого».
0xd34df00d
Вывод типов для достаточно мощных систем типов, например. Или статический анализ нетривиальных свойств на непредназначенном для этого изначально языке без false positive'ов и false negative'ов.
Ну, строго говоря, запрещает Райс, но это одного поля ягоды.
Боюсь, что я недостаточно хорошо знаю питон, чтобы сравнение было репрезентативным.
Не называете ли вы тут протезом условный бульдозер, утверждая, что есть люди, способные
тайпчекать в головеделать то же, что делает бульдозер, и для которых он является протезом?YChebotaev
Что-то я не понял что конкретно он запрещает. Берем JavaScript. Добавляем в него flow на уровне V8, пишем пропозал, пропозал принимают. Что там Райс запрещает я не понимаю.
На уровне личных ощущений. Сами все поймете.
А с чего вы взяли, что на производительность программиста влияет именно типизация, а не Intellisense в IDE? Я думаю, что Intellisense влияет больше, чем типизация.
AnthonyMikh
С того, что внятный Intellisense куда проще прикрутить к статически типизированному языку.
YChebotaev
Не поспоришь. Но тогда на производительность программиста влияет возможность статического анализа, а не типизация.
AnthonyMikh
… Который можно сделать более простым и точным в статически типизированных языках, при прочих равных.
YChebotaev
Вот это самое «при прочих равных» портит всю малину. Я не знаю кейсов, где эти самые «прочие равные» имели бы место.
0xd34df00d
Он запрещает автоматически вывести типы и аннотации для всех библиотек, например. Или иметь такую систему типов, в которой можно (разрешимо) типизировать любой семантически валидный сегодня JS-код.
Так это же и будет означать субъективную продуктивность, разве нет?
А с питоном я на порядки менее продуктивен, чем с хаскелем, например, если программа маленькая, и в бесконечное число раз менее продуктивен, если большая (потому что на питоне я её не способен закончить никогда).
Только интеллисенс, который пытается выводить типы, ломается даже на простейших примерах.
YChebotaev
Во flow это делается не автоматически. Если библиотека экспортирует для себя декларации типов, flow ее подхватывает. Если нет то нет.
До тех пор, пока у вас нет скрытой цели, ваша оценка будет достоверно отражать реальность.
Не, ну понятно, что психологические проблемы разные бывают. Говорить о продуктивности имеет смысл только после того, как все психологические проблемы решены и вам ничего не мешает. Иначе разговор про систему типов превратится в перечисление тараканов.
У меня не ломается. Про какой именно интеллисенс вы говорите? В какой среде? На каком языке?
artur_soloviev
Разве что не пишут на языках без типизации? =)
YChebotaev
Пишут. Одни из самых популярных языков в мире — JavaScript, PHP и Python.
Doomsday_nxt
Тут не об этом вопрос… Если ли у них выбор?
YChebotaev
Конечно. Если бы статическая типизация была такой полезной, как ее малюют, программисты быстро бы расширили эти языки системой типов.
Более того, у нас есть кейсы с TypeScript и flow, и есть доклад, где прямо говорится, что для них статическая типизация практически не играет роли. (Небольшой эффект наблюдается при рефакторинге, но мы все прекрасно знаем, что рефакторинг — развлекаловка разработчика, ценности он не несет).
Doomsday_nxt
это вы сейчас всё серьёзно?
YChebotaev
По тону понятно, что вы не согласны, но пока вы не сформулируете аргумент, я не могу ничего на это ответить.
AnthonyMikh
Не согласен. В достаточно выразительных языках можно получить гарантии, которые попросту невыразимы на более простых языках: раз, два. Да, язык не даёт автоматически ошибкоустойчивый дизайн, но если язык не позволяет сделать подобный дизайн, то он вам в этом смысле не поможет, какой бы крутой разработчик у вас бы не был.
Doomsday_nxt
Назовите меня мракобесом — но я считаю что язык с хорошей и грамотной архитектурой отловит 99% процентов багов при компиляции или статическом анализе
0xd34df00d
Полностью с вами согласен. Осталось определить, что мы считаем хорошей и грамотной архитектурой языка. Как по мне, так это система типов, а статический анализ, соответственно — тайпчекинг.
Doomsday_nxt
Так ответ уже есть — «хорошая и грамотная архитектура языка», это та, которая обеспечивает нахождение багов во время компиляции или статического анализа с вероятностью 99% )))
YChebotaev
Ну так а зачем вам гарантии от самого себя? Когда вы из файла или из базы читаете бяку, типизация вам вообще никак не поможет.
Типизация сильно помогает обучению, это правда и чем она строже, тем лучше. Но после того как вы научились программировать, типизация уже практически не влияет. Расставлять типы и думать об отказоустойчивом дизайне в современной парадигме просто невозможно — в любой момент концепция может поменяться и весь ваш дизайн придется с нуля переделывать.
0xd34df00d
Типизация может помочь убедиться, что у меня есть рантайм-проверки, бяка пришла из БД (или из сокета) или нет.
Наверное, я занимаюсь чем-то не тем, но типизация очень помогает и тут. Особенно когда дизайн переделывается не с нуля, а с сохранением каких-то уже написанных кусков кода.
YChebotaev
Как? Допустим прочитали вы файл в строку. Что-то я не знаю такой системы типов, которая могла бы такие случаи анализировать.
Как вы это поняли? Вы переписываете модуль и у вас нет ошибок компиляции? Ну так может вы просто хороший программист?
0xd34df00d
Ну давайте поиграем в игру. Я прочитал файл в строку (ну или для простоты число, всё, что работает для чисел, сработает и для строк, просто писанины будет меньше). Что вы хотите провалидировать?
Переписываю модуль, и после того, как я поборол все ошибки тайпчекера, все интеграционные тесты зелёные сразу.
YChebotaev
Я хочу, чтобы компилятор с помощью системы типов сказал мне что будет ай-ай-ай.
Ну практически вы говорите что полезно иметь реестр дефектов. И хорошо бы чтобы дефекты выявлялись автоматически. Спорить с этим бессмысленно, я полностью согласен с этими утверждением, но почему вы приписываете достижения статического анализатора системе типов?
AnthonyMikh
В динамически типизированном языке точно также придётся переделывать, только при это у вас не будет компилятора, который подскажет, где изменения забыли внести.
Guzergus
Не затруднит ли вас привести конкретный пример с динамический типизацией, которая позволит вам менять дизайн быстрее, чем со статической?
YChebotaev
Мой аргумент не в защиту динамической типизации, как единственной альтернативе статической. Мой аргумент про то, что типизация оказывает разве что психологический эффект.
Я вообще не считаю, что сама концепция тип объекта хоть сколько-то продуктивна. В реальной жизни объект проявляет себя только во взаимодействии с другими объектами, у него нет и не может быть универсальных черт, истинных с любой точки зрения. Концепт трейта мне видится более жизнеспособным.
А те задачи, которые сейчас выполняет типизация на уровне языка имеет больше смысла производить на уровне IDE: в реальном времени подсказывать программисту доступные возможности, ограничения, документацию, примеры использования, ограничения параметров и все остальное.
mayorovp
Вы так пишете, как будто трейты — не статическая типизация.
Чтобы IDE могла чего-то там подсказывать, надо чтобы кто-то описал статические типы, пусть даже в документации.
Guzergus
С одной стороны соглашусь, но в целом логика опасная. Если язык позволяет мне на этапе компиляции увидеть, что я забыл обработать null ref — при прочих равных этот язык лучше. Можно заставить программиста по несколько раз пересматривать свой код, городить стены тестов, но зачем?
Напомнило, как у нас были проблемы с внесением изменений в один конкретный сервис, в котором архитектура отличалась от остальных. Авторы сервиса в ответ предложили «просто писать без багов». Спасибо, но лучше я буду считать себя глупым и невнимательным разработчиком и напишу так, чтобы потом поддерживать было легче.
0x1000000
Подобными качествами обладают и другие функциональные языки, и выбор в пользу F# тут совсем не очевиден. Начиная с того, что он тащит с собой рантайм со сборщиком мусора и проверкой типов, который в функциональном языке особо-то и не нужен, заканчивая тем, что все библиотеки/фреймворки в .Net пишутся в первую очередь под C#.
Shatun
Можете раскрыть мысль?
По моим ощущениям необходимость типизации зависит скорее от объема проекта, а сборщик мусора вообще ортоганален понятиям ООП vs функциональщина, зависит от задач.
0x1000000
Я говорил не про типизацию как таковую, а про то, что все проверки типов можно было бы полностью выполнить на этапе компиляции.
С ограничением мутабельности становится возможным отследить моменты, когда выделенная память может быть освобождена и освобождать ее сразу же, делая выполнение программы более предсказуемым (без внезапных остановок на сбор мусора).
lostmsu
Основная причина отстутсвтия популярности F# — это отсутствие решарпера и медленный компилятор.
По крайней мере это то, почему я вернулся на C# после нескольких лет, когда понадобилось написать крупный проект.
kagetoki
Ну теперь есть райдер от жидбрейнсов, а в последних версиях команда сильно работала над улучшением перформанса компилятора и тулинга.
Так что можно обратно на F#!
lostmsu
Этот райдер в F# хотябы умеет методы между модулями/классами носить? Сдаётся мне он также ограничен, как F# IntelliSense в студии.