История изменений
Исправление AndreyKl, (текущая версия) :
Мутабельность вообще говоря проблема а не решение. Ты прямо либо не совсем понимаешь о чём говоришь, либо лукавишь. В целом если нет мутабельности, то нет многих ошибок, например
1) Нет Aliasing Bugs - когда ты передал список в функцию, ты на 100% уверен, что после вызова список остался прежним. Это делает код предсказуемым. В мутабельных языках протухшая где то в другом месте переменная - притча во языцах
2) Data Races - Поскольку данные нельзя менять, их можно безопасно читать из любого количества потоков одновременно. Не нужны никакие блокировки (мьютексы) вообще для большинства структур данных. Ты говоришь что чего то там решают линзы, но там где нужны мьютексы в императивных языках, в функциональных просто не нужны ни линзы ни мьютексы, просто читай сколько хочешь.
То что функции являются «чистыми» позволяет гораздо проще понимать что они делают.
В целом высокий уровень абстракций и иммутабельность позволяют писать код практически без ошибок и заметно быстрее чем в традиционных языках (он банально заметно короче и лучше композится)
Некоторое время назад группа исследователей из Пенсильванского университета сделала формальную верификацию основных библиотек из хаскелевских containers. В частности были проверены Data.Set (множества), Data.Map (словари), IntSet. В коде Data.Set и Data.Map не было найдено ни одного серьезного бага.
Это подтвердило что хорошо протестированный код на чисто функциональном языке по качеству практически не уступает формально верифицированному. Типизация и чистота функций сами по себе отсекают 99% проблем.
Есть также работы компании Galois, Inc., которая десятилетиями использует Haskell для оборонных и аэрокосмических заказов. Они подтверждают, что использование таких языков позволяет находить ошибки на этапе компиляции, которые в C++ или Java «выстрелили» бы только в продакшине.
Пенальти по производительности. Окамль к примеру где то на 30% медленне раст в реальных сценариях для веб, примерно на уровне с го.
Внутренние тесты сообщества Retro-httpaf-bench показывают, что современные серверы на базе библиотеки Eio (эффекты для OCaml 5) могут обрабатывать сотни тысяч запросов в секунду, приближаясь к результатам Rust/Hyper на многоядерных машинах.
Если очень хочется , в функциональных языках можно использогвать мутабельность (так конечно делают мало)
По поводу монад - на самом деле как сказал один умный человек всё что мы хотим по большому счёту - это честность. Если мы делаем ввод вывод и работаем с переменным окружением - мы испльзуем IO в хаскеле. И программист и компилятор понимаю что здесь код не будет повторяемым от запуска к запуску. И т.п.
Если говорить о том что можно делать а что делают бедолаги - посмотри на эффекты 1-класса Ocaml5:
Положим, у нас функция для чтения группы файлов (пишу на питоне/псевдопитоне)
def read_files_content(file_paths):
contents = []
for path in file_paths:
with open(path, 'r', encoding='utf-8') as f:
contents.append(f.read())
return contents
Так вот, задачи: есть два варианта использования этой функции 1) мы читаем список текстовых файлов и хотим его условно погрепать на строку ЧЧЧ, нам просто надо знать сколько раз в этих файлах втретилась строка 2) мы читаем список файлов и хотим из них собрать архив (т.е. файлы - части архива).
Понятно, что для задачи 2 всё должно работать, мы кидаем исключение и просто ничего не делаем. Что будет решением задачи 1? ну, условно, другая функция (ну или пляски).
Что позволяют эффекты в Ocaml: мы можем выполнить эффект (это как бросить исключение, только ключевое слово не raise а perform).
Условно, бросаем исключение, но в отличие от исключений, мы когда его ловим, можем сказать либо «бросить настоящее исключение», либо «вернуться в ту же точку программы из которой мы произвели эффект и вернуть пустую строку вместо контента файла»
Т.е. вернуться прямо внутрь функции на ,положим, пятую итерацию цикла for, понимаешь? Причём всё это работает со стеком, а не с кучей (как исключения обычно), соотвественно, работает быстро.
Выглядит всё это близко к конструкции try-catch в обычных языках, т.е. просто описываем что возвращаем:
//здесь говорим что надо вернуться и продолжить
try
content = read_files_content (file_list)
catch
Exception -> return_eff ("", continue)
//а здесь просто игнорируем исключение, поймает кто то выше или вывалимся с ошибкой, всё как обычно
content = read_files_content (file_list)
Эффекты активно используются в Eio - окамлевской библиотеке ввода-вывода предназначенная для создания высокопроизводительных, конкурентных приложений.
Теперь вспомни свой го или на чём ты там пишешь. И про количество ошибок вспомни и про возможности.
Реальные проблемы в том, что в России работу найти практически не реально. Вероятно придётся когда то поехать в Казахстан или переквалифицироваться в управдомы.
Низкую популярность лично я связываю с тем что когда ты молод и зелен мозг ещё хлипкий и уровень абстракции функциональных языков для него проблема - проще писать на императивных.
А когда ты уже синьор - вложены годы труда, нафига переквалифицироваться если всё и так хорошо.
ТС, линзами не пользуюсь, но люди любят.
Исправление AndreyKl, :
Мутабельность вообще говоря проблема а не решение. Ты прямо либо не совсем понимаешь о чём говоришь, либо лукавишь. В целом если нет мутабельности, то нет многих ошибок, например
1) Нет Aliasing Bugs - когда ты передал список в функцию, ты на 100% уверен, что после вызова список остался прежним. Это делает код предсказуемым. В мутабельных языках протухшая где то в другом месте переменная - притча во языцах
2) Data Races - Поскольку данные нельзя менять, их можно безопасно читать из любого количества потоков одновременно. Не нужны никакие блокировки (мьютексы) вообще для большинства структур данных. Ты говоришь что чего то там решают линзы, но там где нужны мьютексы в императивных языках, в функциональных просто не нужны ни линзы ни мьютексы, просто читай сколько хочешь.
То что функции являются «чистыми» позволяет гораздо проще понимать что они делают.
В целом высокий уровень абстракций и иммутабельность позволяют писать код практически без ошибок и заметно быстрее чем в традиционных языках (он банально заметно короче и лучше композится)
Некоторое время назад группа исследователей из Пенсильванского университета сделала формальную верификацию основных библиотек из хаскелевских containers. В частности были проверены Data.Set (множества), Data.Map (словари), IntSet. В коде Data.Set и Data.Map не было найдено ни одного серьезного бага.
Это подтвердило что хорошо протестированный код на чисто функциональном языке по качеству практически не уступает формально верифицированному. Типизация и чистота функций сами по себе отсекают 99% проблем.
Есть также работы компании Galois, Inc., которая десятилетиями использует Haskell для оборонных и аэрокосмических заказов. Они подтверждают, что использование таких языков позволяет находить ошибки на этапе компиляции, которые в C++ или Java «выстрелили» бы только в продакшине.
Пенальти по производительности. Окамль к примеру где то на 30% медленне раст в реальных сценариях для веб, примерно на уровне с го.
Внутренние тесты сообщества Retro-httpaf-bench показывают, что современные серверы на базе библиотеки Eio (эффекты для OCaml 5) могут обрабатывать сотни тысяч запросов в секунду, приближаясь к результатам Rust/Hyper на многоядерных машинах.
Если очень хочется , в функциональных языках можно использогвать мутабельность (так конечно делают мало)
По поводу монад - на самом деле как сказал один умный человек всё что мы хотим по большому счёту - это честность. Если мы делаем ввод вывод и работаем с переменным окружением - мы испльзуем IO в хаскеле. И программист и компилятор понимаю что здесь код не будет повторяемым от запуска к запуску. И т.п.
Если говорить о том что можно делать а что делают бедолаги - посмотри на эффекты 1-класса Ocaml5:
положим, у нас функция для чтения группы файлов (пишу на питоне/псевдопитоне)
def read_files_content(file_paths):
contents = []
for path in file_paths:
with open(path, 'r', encoding='utf-8') as f:
contents.append(f.read())
return contents
так вот, задачи: есть два варианта использования этой функции 1) мы читаем список текстовых файлов и хотим его условно погрепать на строку ЧЧЧ, нам просто надо знать сколько раз в этих файлах втретилась строка 2) мы читаем список файлов и хотим из них собрать архив (т.е. файлы - части архива).
понятно, что для задачи 2 всё должно работать, мы кидаем исключение и просто ничего не делаем? что будет решением задачи 1? ну, условно, другая функция (ну или пляски).
Что позволяют эффекты в Ocaml: мы можем выполнить эффект (это как бросить исключение, только ключевое слово не raise а perform).
Условно, бросаем исключение, но в отличие от исключений, мы когда его ловим, можем сказать либо «бросить настоящее исключение», либо «вернуться в ту же точку программы из которой мы произвели эффект и вернуть пустую строку вместо контента файла»
Т.е. вернуться прямо внутрь функции на ,положим, пятую итерацию цикла for, понимаешь? Причём всё это работает со стеком, а не с кучей (как исключения обычно), соотвественно, работает быстро.
Выглядит всё это близко к конструкции try-catch в обычных языках, т.е. просто описываем что возвращаем:
//здесь говорим что надо вернуться и продолжить
try
content = read_files_content (file_list)
catch
Exception -> return_eff ("", continue)
//а здесь просто игнорируем исключение, поймает кто то выше или вывалимся с ошибкой, всё как обычно
content = read_files_content (file_list)
Эффекты активно используются в Eio - окамлевской библиотеке ввода-вывода предназначенная для создания высокопроизводительных, конкурентных приложений.
Теперь вспомни свой го или на чём ты там пишешь. И про количество ошибок вспомни и про возможности.
Реальные проблемы в том, что в России работу найти практически не реально. Вероятно придётся когда то поехать в Казахстан или переквалифицироваться в управдомы.
Низкую популярность лично я связываю это с тем что когда ты молод и зелен мозг ещё хлипкий и уровень абстракции функциональных языков для него проблема - проще писать на императивных.
А когда ты уже синьор - вложены годы труда, нафига переквалифицироваться если всё и так хорошо.
ТС, линзами не пользуюсь, но люди любят.
Исходная версия AndreyKl, :
Мутабельность вообще говоря проблема а не решение. Ты прямо либо не совсем понимаешь о чём говоришь, либо лукавишь. В целом если нет мутабельности, то нет многих ошибок, например
1) Нет Aliasing Bugs - когда ты передал список в функцию, ты на 100% уверен, что после вызова список остался прежним. Это делает код предсказуемым. В мутабельных языках протухшая где то в другом месте переменная - притча во языцах
2) Data Races - Поскольку данные нельзя менять, их можно безопасно читать из любого количества потоков одновременно. Не нужны никакие блокировки (мьютексы) вообще для большинства структур данных. Ты говоришь что чего то там решают линзы, но там где нужны мьютексы в императивных языках, в функциональных просто не нужны ни линзы ни мьютексы, просто читай сколько хочешь.
то что функции являются «чистыми» позволяет гораздо проще понимать что они делают.
в целом высокий уровень абстракций и иммутабельность позволяют писать код практически без ошибок и заметно быстрее чем в традиционных языках (он банально заметно короче и лучше композится)
Некоторое время назад группа исследователей из Пенсильванского университета сделала формальную верификацию основных библиотек из хаскелевских containers. В частности были проверены Data.Set (множества), Data.Map (словари), IntSet. В коде Data.Set и Data.Map не было найдено ни одного серьезного бага.
Это подтвердило что хорошо протестированный код на чисто функциональном языке по качеству практически не уступает формально верифицированному. Типизация и чистота функций сами по себе отсекают 99% проблем.
Есть также работы компании Galois, Inc., которая десятилетиями использует Haskell для оборонных и аэрокосмических заказов. Они подтверждают, что использование таких языков позволяет находить ошибки на этапе компиляции, которые в C++ или Java «выстрелили» бы только в продакшине.
Пенальти по производительности. Окамль к примеру где то на 30% медленне раст в реальных сценариях для веб, примерно на уровне с го.
Внутренние тесты сообщества Retro-httpaf-bench показывают, что современные серверы на базе библиотеки Eio (эффекты для OCaml 5) могут обрабатывать сотни тысяч запросов в секунду, приближаясь к результатам Rust/Hyper на многоядерных машинах.
Если очень хочется , в функциональных языках можно использогвать мутабельность (так конечно делают мало)
По поводу монад - на самом деле как сказал один умный человек всё что мы хотим по большому счёту - это честность. Если мы делаем ввод вывод и работаем с переменным окружением - мы испльзуем IO в хаскеле. И программист и компилятор понимаю что здесь код не будет повторяемым от запуска к запуску. И т.п.
Если говорить о том что можно делать а что делают калеки - посмотри на эффекты 1-класса Ocaml5:
положим, у нас функция для чтения группы файлов (пишу на питоне/псевдопитоне)
def read_files_content(file_paths):
contents = []
for path in file_paths:
with open(path, 'r', encoding='utf-8') as f:
contents.append(f.read())
return contents
так вот, задачи: есть два варианта использования этой функции 1) мы читаем список текстовых файлов и хотим его условно погрепать на строку ЧЧЧ, нам просто надо знать сколько раз в этих файлах втретилась строка 2) мы читаем список файлов и хотим из них собрать архив (т.е. файлы - части архива).
понятно, что для задачи 2 всё должно работать, мы кидаем исключение и просто ничего не делаем? что будет решением задачи 1? ну, условно, другая функция (ну или пляски).
Что позволяют эффекты в Ocaml: мы можем выполнить эффект (это как бросить исключение, только ключевое слово не raise а perform).
Условно, бросаем исключение, но в отличие от исключений, мы когда его ловим, можем сказать либо «бросить настоящее исключение», либо «вернуться в ту же точку программы из которой мы произвели эффект и вернуть пустую строку вместо контента файла»
Т.е. вернуться прямо внутрь функции на ,положим, пятую итерацию цикла for, понимаешь? Причём всё это работает со стеком, а не с кучей (как исключения обычно), соотвественно, работает быстро.
Выглядит всё это близко к конструкции try-catch в обычных языках, т.е. просто описываем что возвращаем:
//здесь говорим что надо вернуться и продолжить
try
content = read_files_content (file_list)
catch
Exception -> return_eff ("", continue)
//а здесь просто игнорируем исключение, поймает кто то выше или вывалимся с ошибкой, всё как обычно
content = read_files_content (file_list)
Теперь вспомни свой го или на чём ты там пишешь. И про количество ошибок вспомни и про возможности.
Реальные проблемы в том, что в России работу найти практически не реально. Вероятно придётся когда то поехать в Казахстан или переквалифицироваться в управдомы.
Низкую популярность лично я связываю это с тем что когда ты молод и зелен мозг ещё хлипкий и уровень абстракции функциональных языков для него проблема - проще писать на императивных.
А когда ты уже синьор - вложены годы труда, нафига переквалифицироваться если всё и так хорошо.
ТС, линзами не пользуюсь, но люди любят.