Pull to refresh
4
0
Вагиф Абилов @VagifAbilov

Пользователь

Send message
Хм, в той таблице C# хотят изучать 8%, а F# — 4%. Ruby где-то посередине. По этим цифрам невозможно сделать какой-то фатальный вывод. Да и вообще, если обращаться к цифрам, имеет смысл обращать внимание не на то, что привлекает массовый интерес, а на то, как обстоит с работой и проектами в том, чем хотелось бы заниматься. Если нет вокруг проектов на языке, на котором хотелось бы писать, то это разумный аргумент, чтобы все не бросать и ждать, пока появится. Но и здесь преимущество нашей профессии — что можно что-то изучать в свободное время, дожидаясь возможности это применить. У меня лично года четыре прошло с момента, когда я понял, что мне хочется программировать на F# и стал его потихоньку осваивать, до того, как я смог на нем программировать за деньги. Сейчас, думаю, ситуация значительно улучшилась.
Ну я выше привел некоторые мои аргументы «зачем», в частности о том, что еще F# может предложить кроме иммутабельных типов. Плюс в статье есть ссылка на хабровское интервью, где более подробно говорю о причинах. А «успокаиваю» я вас потому, что аргументы у каждого могут быть свои и для других они могут быть неубедительны. Первичным должно быть осознание неффективнсти текущего метода написания кода, желание что-то с этим сделать.
Уже отвечал в других местах, но повторюсь, что являлось главным для меня:
— immutability by default, т.е. по умолчанию никакие структуры данных нельзя мутировать.
— type inference, автоматический вывод типов. Вообще сильная типизация позволила мне вытаскивать ошибки кода в основном при компиляции, в C# я на все тесты писал.
— discriminated union для доменного моделирования. Компактно и читабельно.
Если вас абсолютно все устраивает в том языке, на котором вы пишете (C#?), то нет ничего зазорного на нем же и продолжать. Большинство переходящих на F# делают это после многих лет работы на C#, будучи неудовлетворены эффективностью написания на нем кода. Надо просто как-то созреть если не для перехода, то по крайней мере, чтобы попробовать писать код по-другому. К этом прийти никогда не поздно, если у вас для этого сейчас нет причин, то в этом нет ничего страшного.
Разумеется! Просты мы начали копаться в IEnumerable (хоть и моей подачи).
Вы правы. Я имел в виду использование yield, но yield не работает с async/await. Но можно вернуть IEnumerable of Task of string, как здесь предлагают:

ctigeek.net/using-asyncawait-with-ienumerable-and-yield-return
А почему из другой формы пользовательского ввода нельзя создать поток, который бы питался из IEnumerable string?
Добрый день. Посольку самые разные источники данных можно сконфигурировать как источники потока (stream source), то можно использовать практически все что угодно — все, из чего можно извлечь Stream, Task, IEnumerable etc. Т.е. если у вас на входе пользователь время от времени вводит какие-то строки, их можно подавать в поток как IEnumerable<string>.
Влад, так в том-то и дело, что такой стиль написания на ОПП не считается однозначно правильным. Я согласен, что не надо очень напирать на краткость кода на ФП, это в конце концов не самоцель, хоть и полезно, но церемониальность многих языков ООП не связана с ООП как таковым, и при желании их тоже можно сделать более компактными. Вот здесь — набор слайдов, где предлагается синтакс языка C# Light, при использовании которого код становится сравнимым по компактности с фшарпом:

https://www.slideshare.net/ScottWlaschin/c-light

Но если брать другие, более важные моменты, то основная проблема языков ООП — это то, что они навсегда останутся языками мутирующих данных. Мы можем требовать от разработчиков команды высокой дисциплины, но нельзя заменить основы языка дисциплиной. Вот пересказ отзыва создателя Clojure Рич Хики о проблемах мутаций в ООП:

«It should also be obvious that OO languages have „no proper notion“ of values in this sense. As Rich Hickey points out, you can create a class whose instances are composed of immutable components, but there is no high-level concept of immutable value implemented as a first class construct within the class.

This is one of the main causes of headaches when doing OOP. How many times have you pulled your hair out trying to figure out how an object's attribute got changed? The fact is, in OO languages there is no built-in mechanism to ensure that the object you're dealing with is stable.

This is the big reason why concurrent programming is so difficult.»

Безусловно, современные C# и Java куда более пригодны для функционального стиля программирования, чем пятнадцать лет назад. Но такой стиль всегда будет оставаться для этих языков если не инородным, то по крайней мере не самым идиоматическим.
Переходя на LINQ, мы уже зачастую переходим на элементы функционального программирования. В вашем примере цепочка из Enumerable.Range -> Select -> Select — это ли не функцинальные трансформации? Обратите еще внимание, что вы решаете задачу для доски конечного размера, в то время как игра Конвея предполагает бесконечную доску (решение на фшарпе, о котором я говорил, не ограничивает размер доски).
Если же брать примеры непосредственно из ФП, то какой-нибудь List.fold поначалу может и требует задуматься, что же там внутри происходит. Но пройдя через это и поняв, выходишь на иной уровень абстракции, выигрывая на нем в компактности.
Ну вот возьмите async/await. Вроде бы это всего лишь синтактический сахар. Но реально уменьшает количество кода, а раз так, то и шанс сделать логическую ошибку. Я себя причисляю к той части программистов, которая чем больше пишет, тем больше ошибается, для таких, как я, компактность кода — это благо.
Это верное замечение, мне следовало лучше обговорить, что я имею в виду под важностью аспекта. ФП действительно управляется типами, но благодаря type inference их часто можно не вводить для промежуточных вычислений. Partial application тоже помогает на них не сосредоточиваться. Но ФП именно что начинается с типов — дальше они пускаются в плавание по трансформациями. ООП и начинается, и продолжается, и заканчивается типами, собственно парадигма такая, от нее не убежать. И это приводит к тому, что в реальной практике мы часто слишком многое определяем заранее, связывая свой дизайн.
В прошлом году Джо Армстронг (Erlang) делал доклад на NDC о принципах, заложенных в язык, и он как раз упирал на то, что в основе успеха Эрланга у телеоператоров и прочих систем, требующих масштабируемости и надежности — соответствие Эрланга (функционального языка) железу, на котором будут запускаться программы на нем. «We do not have ONE web-server handling 2 millions sessions. We have 2 million webservers handling one session each.» — сказал он же в другом месте. То есть несмотря на императивность и мутабельность архитектуры процессоров процессы на них имеет смысл запускать функциональные и неизменяемые.
Думаю, обобщенный ответ на этот вопрос лежит вне парадигмы программирования. Хотя в рамках некоторых моделей есть свои решения. Например, мы пользуемся моделей актеров — она доступна и из ООП, и из ФП, но поскольку актеры (или акторы, тоже не уверен, как лучше по-русски выразиться) не делят состояния, то по духу ФП ближе, не даром Akka пришла из Скалы. Так вот, в рамках этой модели у нас некоторые актеры хранят разделяемое состояние, доступ к котрому осуществляется путем обмена с ними сообщениями. Это может выглядеть тяжеловесно, позволяет полностью обходиться без замков.
Сразу оговорюсь, что опытом кручения гигантских матриц не обладаю, но судя по разным бенчмаркам, при особых требованиях к быстродействию F# уступит не только Си++, но и некоторые его модули (List, Map) проиграют по скорости структурам данных из .NET/C#. Если не ошибаюсь, Ayende (Oren Eni) делал сравнения, писал в своем блоге.
В более традиционных системах, однако, закон Амдала, указывающий на потери быстродействия залоченных данных, имхо, делает код с замками в многопоточной среде более уязвимым в плане быстродействия, чем функциональные алгоритмы без блокировки.
Нет, не означает, конечно. Я и сейчас немало пишу на C#, переходил на него с Си++ с удовольствием. Что же до чужих библиотек, то речь идет непосредственно о коде, который пишем мы сами, о его прочности, о пригодности к параллелизации. Сопровождать же нужно будет свой домашний код, а не другие библиотеки.
Так это и есть оригинальный текст, мы беседовали по-русски.
Спасибо за поправку. Я не знал. Долго думал, как же это перевести, остановился на «внедрении».
1

Information

Rating
Does not participate
Location
Akershus, Норвегия
Date of birth
Registered
Activity