Pull to refresh
4
0

Haskell разработчик

Send message
которые вообще-то костыль для изменения вложенных иммутабельных структур, а никак не лучшее изобретение

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


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

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


foo :: (MonadWriter String m, MonadBar m) => Int -> m String

А это один из мощнейших инструментов для:
а) инверсии контроля, а соответственно тестирования и переиспользования кода
б) композиции разных алгебр в tagless final
в) контроля за эффектами по типу (поход в базу, запись в лог, генерация рандомного числа, етк)
Я бы не сказал, что это "просто чуть менее удобно".


Работать на нём — нет спасибо, у меня семья)

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

Чем ещё хорош F# — это практичный язык, который не претендует на звание чистого, как Хаскель.

Но чистота очень даже практична. "Не практична" у хаскеля как раз сырая экосистема. Как язык хаскель всё же куда проще, понятнее и практичнее чем его "аналоги" из JVM и .Net мира.


Вон те же линзы, которые изобрели в хаскеле, ИМХО, самое практичное, что есть в программировании. На втором месте в моём топе практичности монады + tagless final, которые очень упрощают тестирование и переиспользование кода. Ленивость тоже практичная штука с точки зрения "писать декларативный код и заранее не париться об оптимизации".

полиморфизм = неявные касты

Не равно.


Получается из хаскеля джаваскрипт.

Не получается.


Там и обычный-то полиморфизм запрещать стоит

Без полиморфизма нет инверсии контроля, без инверсии контроля даже банального юнит тестирования не сваришь, что уж говорить о развесистой бизнес-логике.

Проще наверное сказать где каналов нет, чем где они есть.


На всякий случай добавлю — да, естественно в Rust есть каналы.

Эту лямбду мы тоже должны как-то в другой поток передать, а в Rust компилятор это так же может отследить.

map (\x -> x ^ if x < 0 then 3 else 2) $ filter odd [-2 .. 5]

Сиподобная тернарка это ну такое. Функции в обратную сторону тоже, хотя при желании можно написать конечно и так:


[-2 .. 5] & filter odd & map (\x -> x ^ if x < 0 then 3 else 2)

А опыт и привычки CTO значит никак не зависят от поисковой выдачи и прочего маркетинга? Как-то слишком уж наивна мысль о том, что выбор языка программирования зависит только от каких-то объективных факторов.

Вы так говорите, будто не влияет. SEO, между прочим, очень важная штука для продвижения сайта/продукта/технологии, сейчас возможно даже самая важная.

Ну, видимо, есть, раз один из авторов Go утверждает, что идея заимствована из хаскеля, за основу взята C++-реализация.

Ну раз один из авторов Go утверждает, то конечно.

Но есть же [в IO].

Обычно для обработки ошибок в языках, где для этого не принято использовать исключения используются типы-суммы, например Result из Rust или Either из Haskell.

Без unsafe их писать сложно. Использовать их чуть более удобно, чем в других языках без GC. До языков с GC удобство использования конечно не дотягивает.


На самом деле подобные рекурсивные структуры в императивных языках используются довольно редко, в системном программировании же ещё реже.

У вашего варианта есть фатальный недостаток. Что если вам понадобятся унарные или тринарные операции?


В функциональных языках есть один очень популярный паттерн — интерпретатор. Реализуется он обычно либо при помощи tagless final кодирования выражений, либо при помощи GADT. GADT в Rust нету, а вот простенький tagless final мы можем сделать используя трейты.


Можно объявить трейт Expression


trait Expression {
  fn add(&self, right: &Self) -> Self;
  fn sub(&self, right: &Self) -> Self;
  fn negate(&self) -> Self;
  fn eq(&self, right: &Self) -> Bool;
}

И сделать для него конкретные реализации, каждая реализация будет конкретным интерпретатором. Например одна реализация будет возвращать строку для вывода, вторая считать результат выражения, третья просто дублировать значение для того, что-бы одно выражение превратить в два выражения, с разными типами.


Для расширения Expression можно использовать "наследование" трейтов (хотя в большинстве случаев будет проще и лучше запихать операцию в изначальный трейт):


trait ExpressionMul : Expression {
  fn mul(&self, right: &Self) -> Self;
}

Для удобства потом можно сделать функции, которые будут фиксировать тип в нужном месте.


fn eval(i: i64) -> i64 { i }
fn stringify(s: String) -> String { s }
fn double<E1: ExpressionMul, E2: ExpressionMul>(pair: (E1, E2)) -> (E1, E2) { pair } 
Политика. — Высосано из пальца. Может быть так, а может быть иначе. Неявное разделение есть в любом языке и проекте.

Зато есть весьма явное высказывание о Golang от Роба Пайка о том для кого и зачем делался язык.


Пакеты и GOPATH. — уже на дворе 1.11 и это исправили.

Вы во всех своих проектах уже на модули переехали?


Обработка ошибок в Go. — скоро завезут гораздо более приятную.

Скоро в хаскель линейные типы завезут. Тем не менее пока это нельзя считать достоинством хаскеля.

Божечки… И сюда таблицу Сыроветского притащили.

И почему вы не упомянули sync.Map, а сразу так отрезали что «их нет»?

У sync.Map есть один огромный минус и имя ему пустой интерфейс.

Вот у нас есть ООП. Инкапсуляция, наследование, полиморфизм. В чём математическая основа этой штуки? Теория множеств? Или группы? Или категории? Как базовые понятия (объект, класс, атрибут, метод) мэппятся на математику? Вот реляционная алгебра, например — прямой потомок исчисления предикатов. А ООП — чей потомок?

Это аргумент против ООП, не против математики.

Таки Rust не столь сложный, чтобы его не смог освоить плюсовик. Да чего уж там, Rust спокойно осваивают те люди, которые с языками без GC были знакомы постольку поскольку и пишут при этом нормально работающий код.

ИМХО, это задача того, у кого возник такой вопрос и кому это интересно, то есть это твоя задача.

Option<&T> не является владеющим указателем, в отличии от unique_ptr, более того, Option<&T> даже "умным" указателем не является, ибо оптимизируется в обычный сырой указатель и имеет значение только на этапе проверки схождения типов.

Information

Rating
Does not participate
Location
Владивосток, Приморский край, Россия
Date of birth
Registered
Activity