усы2

Стой под стрелой

Поступки и мысли, о которых могу вспомнить не краснея

Previous Entry Поделиться Next Entry
Читабельная Кложа
усы2
tonsky
Обнаглел настолько, что код вставляю скриншотами

http://tonsky.me/blog/readable-clojure/

  • 1
(Анонимно)
Не понимаю, почему ты говоришь про это на уровне синтаксиса (и крайне субъективной readability), а не на уровне концепций, представленных этим синтаксисом.

Про Don’t spare names: пайплайн гораздо концептуально более простой, чем граф. И в Avoid higher-order functions функция высокого порядка более концептуально простая, потому что гарантирует определённую манипуляцию с функциями-аргументами (т.е. гарантирует, что ты нигде не добавил аргумент, макро, и т.д.)

Ну и заметка нарушает идею «Совета про советы»: ты рассказываешь, как надо, но не говоришь, почему. За этими приёмами не стоит никакой общей объективной идеи, а последние два совсем вкусовщина.

> Ну и заметка нарушает идею «Совета про советы»: ты рассказываешь, как надо, но не говоришь, почему

ну так все правильно - пипл хавает простые решения, высказаные авторитетно.

Цель — упростить читабельность. Каждое правило кратко поясняет, почему оно упрощает читабельность.

Что значит концептуально более простой? Я не могу думать на уровне концепций, мне нужно конкретно понимать, что в код приходит и что уходит. Жонглировать высшими сущностями не получается.

(Анонимно)
Читабельность — это про лёгкость, относительное и варьирующееся. Мне искренне проще читать comp, partial и т.д. по сравнению с анонимной функцией. Относительная природа читабельности подсказывает, что это не статичное качество и что-то, что кому-то неудобно читать сегодня, может стать удобно читать завтра.

Под «концептуально простым» я подразумеваю простое содержание. Я предлагаю фокусироваться на содержании, а не на форме, думать не о читабельности, а о том, насколько просто (распутанно) изложены сущности. let, например, более сложный чем threading macro (или же просто обычная запись в один длинный s-expression), потому что последнее гарантирует линейность операций, в отличие от let.

Так же и high-order functions упрощают изложение, производя конкретные трансформации функций, в отличие от арбитрарно возможных внутри fn.

В заметке это немного присутствует (декаплинг nil/false), но в то же время & {}, которое можно объяснить как запутывание list/map в одну сущность, ты объясняешь с практической точки зрения (сложно вызывать), в то время как это последствие проблемы.

Не соглашусь. Ты говоришь о формальных свойствах конструкций. Если бы дело было только в них, все было бы так, threading over let, higher-order over анонимки. Они действительно меньше свободы дают, легче понять что происходит «в общих чертах». Ну, какие-то данные тредятся. Ну, какие-то функции комбинируются. Эту «форму конструкции» проще считать.

Заковыка в этом «какие-то». В реальном коде, когда его предметно читаешь, важно _конкретно_ что за функция. Не просто «одна функция с одним аргументом скомбинирована с другой функцией с одним аргументом», а что именно за функции: первая вычисляет зарплату, вторая возраст, например. Важно, что в конструкцию приходит именно тип Юзер, а не абстрактный Х. И так далее. Важно, что с ним делаются _правильные_ вещи. И правильность определяется не тем, правильно ли скомбинированы функции по количеству аргументов, а что конкретно это за функции. И при разборе таких конструкций гораздо проще читать их маленькими порциями. Юзер вошел сюда, применилось это, применилось это, вызвалось вон то, сюда записалось, вышел. В идеале каждый шаг отдельно и с намеком на то, что происходит (промежуточные имена, например). Можно и трединг макрос аннотировать комментариями, будет то же самое. Но опять же, то что это именно трединг, т.е. трансформации над одним и тем же объектом, не так важно для нас, как то, _какие именно_ это трансформации и _что именно_ они возвращают.

И еще момент. Трединг сам по себе это не какая-то семантическая конструкция. Он не несет смысла сам по себе. То, что его применили, не сообщает на семантическом уровне никакой новой информации. Это ровно «так случилось, что ряд операций в данном конкретном случае удобно выстраивается и поэтому сокращается до цепочки». Не больше и не меньше.

Сорри, мутно и расплывчато, но проще не могу объяснить.

(Анонимно)
Сорри, мутно и расплывчато, но проще не могу объяснить.


Нет, всё здорово и понятно :-)

Кложа как инструмент старается решать проблемы максимально абстрактно. Отсюда функциональность, интерфейсы (а не конкретные типы данных), каплинг nil/false (в том числе для совместимости с хостом, но не только), структуры данных, имплементирующие IFn, и т.д.

Мне кажется, то о чём ты говоришь, лучше решать с помощью clojure.spec, а не трансформируя абстрактный код in-place: clojure.spec гораздо более выразительный инструмент для конкретики, и сможет хорошо описать и шейп структуры данных для юзера, и конкретные трансформации, производимые функциями. clojure.spec отделяет implementation details от intent.

И еще момент. Трединг сам по себе это не какая-то семантическая конструкция. Он не несет смысла сам по себе. То, что его применили, не сообщает на семантическом уровне никакой новой информации. Это ровно «так случилось, что ряд операций в данном конкретном случае удобно выстраивается и поэтому сокращается до цепочки». Не больше и не меньше.


Да, конечно. Трединг семантически эквивалентен любой обычной форме. Всё, что я говорил о threading против let, можно читать как plain s-expression vs let.

> Каждое правило кратко поясняет, почему оно упрощает читабельность.

При использовании повелительного наклонения в письменной речи лучше сначала пояснять (обрисовывать бэкграунд), а потом повелевать, а не наоборот. Минимум 2К лет традиции есчо )

Обратный порядок превращает повеление в просьбу об одолжении.

Аргументы гуманитарные, конечно.

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

Ещё аналогичную структуру несут папские буллы, например – но там обычно многословнее и в конце добавлены кары за несоблюдение.

Также обрати внимание на судебные решения: сначала мотивировка, потом приговор.

Это особенность использования авторитета вообще. Перестановка «повеления» в начало превращает обоснование в оправдание.

хм, интересно, попробую как-нибудь сравнить

  • 1
?

Log in

No account? Create an account