Comments 129
Фил, в расте нет наследования, а значит и нет всего класса описаннных тобой проблем.
Перепиши все на раст и вступай в ряды, пора!
Раст шикарен. Как и F#. Но у меня-то работа на сишарпе, куда тут денешься. Хотя нам завозят рекорды, и скоро будут DU, будет получше
Тебя дети читают, подумай, чему ты их учишь )))
Они вырастут и будут спорить какую иерархию классов сделать и как сообщать об эксепшенах в функции.
А должны были вырасти и спорить о том как решить любую задачу человечества через map/reduce
P.S. кстати, а как можно медиану вывести через map/filter/reduce?
filter — частный случай reduce, не? Как и map.
Сортировку же можем, значит и медиану можем
В P.S. я не спрашивал «можем или не можем», я спрашивал «как»
P.S. сообразил, как сделать, чтобы ситуации не надо было различать. Ну ладно, filter — частный случай reduce (но я всё же буду настаивать, что лучше его рассматривать, как самостоятельный инструмент)
P.P.S. Вот, кстати, пример, чем плох filter, реализованный через reduce: для корректной реализации потребуется создать копию исходного кортежа с добавленным пустым кортежем в начало. Это может быть совсем невозможно, если у нас настолько большой кортеж, что занимает большую часть памяти (у «чистого» filter такой проблемы нет, у него может быть проблема только с размещением результата, а тот может быть существенно компактнее)
P.P.P.S. Ну и вдогонку: почему бы тогда и про map не «забывать», если и она частный случай reduce?
Не выдержал, скажу все таки. Зачем нужно отличать первый элемент от остальных, не понимаю не только я, но и все авторы всех имплементаций filter
во всех языках. (Вот, ниже в псевдокоде).
filter(enum, fun) = reduce(enum, new typeof(enum), fn e, acc ->
if fun(e) then append(acc, e) else acc
end)
Я не понял вопрос, извините. Есть Foldable
/ Enumerable
. Кортеж это, список, или массив — дело сто тридцать пятое.
Если на нем определен fold
/ reduce
— то filter
можно определить как показали выше (псевдоязык, haskell
, idris
соответственно).
Типы элементов — значения не имеют вовсе, главное, чтобы фильтрующая функция их понимала.
В шарпе есть FFI и весь новый код после 1 января 2021 должен быть написан на расте в соответствии с сегодняшним Указом Путина «О сокращении выбросов парниковых газов».
Так найди работу на расте и все будет ровно так как ты хочешь.
Надо, да. К сожалению.
И причина не в чистоте кода, а в том что когда у вас будет большой проект с несколькими языками, документацией и т.п. и кто-то решить поискать во всем объеме этой информации по имени класса Api он вас проклянёт, а по LicenseApi найденых вхождений будет на пару порядков меньше.
Мне кажется, или проблема вовсе не в нейминге, а в убогих средствах для поиска?
Статья для дотнетчиков, так что, парни, давайте передохнём минуту и хорошенько поржём над «НАСТРОИТЬ ДЕБАГ».
Да, давайте поржем над Филом и пятью его загадочными сеньорами-фронтами, которые не смогли прочитать документацию электрона.
Когда все необходимые шаги прямо таки разжеваны в первых же ссылках гугла, и вообще сами по себе очень стандартные (запустить процесс с соответствующими дебаг-командами, подключить remote debugger) — тут конечно же без пяти сеньоров не обойтись.
Или у вас такая IDE, что не умеет в это всё, как умеет та же VSCode? Ну так проблема на вашей стороне, надо было брать инструменты, которые умеют.
Я нашел несколько рецептов для VS и WebStorm. Интересно, это пробовали и не подошло (ну мало ли какие там особенности). Или сеньоры специфические.
https://stackoverflow.com/questions/46500302/attach-visual-studio-debugger-to-electron-app
https://blog.jetbrains.com/webstorm/2016/05/getting-started-with-electron-in-webstorm/
Оно вот правда всё работает на уровне «прочти и сделай как написано», по крайней мере в VSCode. Вернее, работало еще в 2018.
Кстати, есть новая мода писать ',' в конце последней строки любого перечисления. Я её ненавижу, потому что, после запятой должно что-то идти.Конкретно в параметрах метода так делать нельзя, в вашем примере будет ошибка компиляции.
MethodName(
parameter1,
parameter1,
parameter1,
parameter1,
parameter1,
)
Ну и сделано это для удобства использования при автогенерации кода, ненужны специальные подпрыгивания, чтобы отслеживать когда надо её ставить, а когда нет.
У этой многострадальной запятой есть ещё одно назначение: при добавлении элемента в список мы не меняем предыдущую строку.
И легче смотреть историю изменений в git.
Ага, работал с таким code style.
Но, в большинстве случаев — это вкусовщина, поэтому я не испытываю эмоций на сей счет.
А если надо новый первый элемент вставить, то опять две строки менять.
Вот так и выходит, что приходится равняться на стандарты тех, кто учиться не хочет и не хочет пробовать новые идеи.
Из всего AOP в практике остались крохи и они AOP даже не называются. Продавали его как серебряную пулю, а получился пшик. С AOP куча проблем — интеграция с IDE и сборкой, ошибки в самом инструменте, отладка аспектов, изучение всего этого, отсутствие известных практик. Все это грабли на которые вам предстоит наступить, те кто поопытнее просто не хотят ещё раз ходить по граблям, работает — не трогай.
Так вот как раз трансформация кода (и AOP как его часть) и автогенерация кода дают тебе этот рычаг. Существует некий порог входа, но когда плечо рычага достигнет опередлённого уровня, тогда появляется новое качество. Опять же работает это не на всех проектах и надо затратить некоторые усилия, но с правильным инструментом это вполне посильно.
Я сильно надеюсь что в конце концов спецификации языка и IDE будут включать подобную поддержку из коробки, ну а пока каждый д… т как он хочет.
Мы даже не знаем проблему определить, кроме как "софт — это сложно"
Я бы еще добавил, что сначала собрать данные показывающие на то, что проблема существует (логов недостаточно, ошибки в дублирующемся логовом коде и т.д.), убедить остальных что это стоит последующих шагов.
Потом провести эксперимент (как вы упоминали) и показать, что он дал какой-то положительный эффект и какие у этого решения недостатки. Потом принять решение о распространении практики.
Некоторым даже за это платят, всякие Technology Advocate.
Он синьоров обычно требуется так же умение убеждать других.
TL;DR: я выстрадал и выкатил 100500 новых правильных практик написания кода: нейминга, форматирования, наследования, инкапсуляции и прочего, но мой код можно понять только изнутри той IDE, которая нравится мне.
Всё так. Только в .net все пишут или в райдере, или в студии с решарпером, который превращает её в райдер. Короче, ide то у всех одна и та же.
Пишут — возможно. Но если я начну накатывать по IDE на каждый язык, который мне приходит на CR, я проведу всю жизнь в установке ненужного мне софта.
Поэтому, что бы себе там ни возомнили разработчики, я буду читать код на GH, а если уж прям приспичит поиграться — то в виме. Насколько код «красивый» — это пусть джуниоры оценивают, а архитектуру и варианты решения узких мест — придется просмотреть и одному из принимающих решения, и этот человек может и не писать код именно в дотнете с утра до вечера.
Так что я все-таки убежден, что код обязан не терять в читаемости безо всяких там IDE.
Я бы подискутировал, на самом деле. Хороший код всегда красивый, красивый код не всегда хороший. Но эти вещи связаны. Эстетическая красота кода — это в том числе и красота архитектуры и дизайна — качества именно хорошего кода.
Кроме того, IDE и её возможности — очевидно со временем в гх и перекочуют. И если компилятор языка умеет отличать исключения от ивента, значит и инструмент для работы с этим языком должен и будет их различать
Хороший код всегда красивый, красивый код не всегда хороший.
Отнюдь. Иногда «годный» код от «хорошего» — отличают бенчмарки, и приходится драться за каждую миллисекунду. И вот тут-то красотой приходится жертвовать. Пример из совсем недавнего: писал я там одну библиотеку, и очень красиво хранил внутреннее состояние в AVL Tree. А потом невзначай выяснилось, что удалений в моем случае практически нет, добавления обычно можно свести к конкатенации, а вот поиск прям частый. И я переписал все на связных списках с костылями, дискретным доступом по типу хэшмапа (O(1)
) и кодогенерацией matching clauses для частых паттернов. И выиграл в производительности в 10 раз.
Стал ли код менее красивым? — Несомненно. И понять его теперь в двадцать раз сложнее.
И если компилятор языка умеет отличать исключения от ивента, значит и инструмент для работы с этим языком должен и будет их различать.
Возможно. Но я не готов запоминать какой цвет в каком языке какому чему соответствует. В нескольких языках из моего активного словарного запаса понятия «интерфейс» вообще нет (elixir). В других — он означает совсем не то же самое, что в шарпе и джаве (idris).
Или вот исключения и ивенты. Что такое ивент? А в языке с нативной моделью акторов? А в джаваскрипте? А в руби? Синий или зеленый? Курсив или болд? А так-то, для общего понимания кода, мне это все не важно: детали реализации. Мне важно, что автор этого кода считает сие ивентом, что я пойму по ключевому слову Event
, а по раскраске не пойму. И если в коде throw new NotifyEvent();
, то тут что-то не так, а если throw new Notification()
, и Notification
красненькое и жирненькое — то я хз.
В общем, с тезисом про то, что код должен доставлять эстетическое наслаждение — я согласен чуть более, чем полностью (с оговорками, конечно, но в общем случае — так). А с тем, что без IDE мне потребуется на понимание в пять раз больше времени, и это нормально — категорически нет.
Есть такая концепция как intelligence amplification — в самом простом случае можно сравнить эффективность решения математических задач в уме vs человеком у которого есть листок бумаги и ручка. Вполне допускаю что существуют те кто в уме будут более эффективно решать, но в целом бумага плюс ручка дают существенную фору.
Также и IDE, правильная IDE является очень эффективным усилителем как качества так и производительности _обычного_ программиста. Даже плагины к ней могут играть существенную роль (VisualStudio vs VisualStudio+ReSharper).
Ээээ… Спасибо на добром слове.
эффективность решения математических задач в уме vs человеком у которого есть листок бумаги и ручка
Не-не-не. Писать код каждый волен в чем ему удобнее — тут вообще никаких вопросов. Я докопался до «не надо заморачиваться самодукентированным кодом, потому что мне IDE все подсветит», и возражаю с точки зрения читающих код.
Код же читают больше и лучше, чем пишут, так вроде кто-то из великих демагогов сказал?
Так вот прочитать код может потребоваться не только ревьюеру, но и человеку из другой команды, другого отдела, другого года. У фронтендера, который пилит свой гуй в своем любимом ТайпСкриптере, внезапно может не оказаться решарпера. У эрлангиста, который ковыряет сорок два микросервиса, гоняющие туда-сюда миллиарды сообщений — тоже. Но им может потребоваться узнать, как там оно реализовано, для каких-то своих нужд. И они пойдут в GH. Ну, я бы пошел, не знаю.
И вот тут-то и окажется, что документация должна быть first class citizen, а интерфейсу хорошо бы прямо с порога заявить о своей принадлежности племени интерфейсов.
Простой пример: хаскель вон типизирован не в пример лучше шарпа, что как бы должно помогать в IDE найти нужную функцию прям по сигнатуре. Но читать хаскель невозможно, если ты не пишешь на нем 24/7 — из-за дикой мешанины бесконечного количества функций в Prelude и стандартных импортах. Тут так же: вся красота, описанная в статье — write-only. Читателю будет легче, если у интерфейса будет префикс. Точка.
И вот тут-то и окажется, что документация должна быть first class citizenВ теории да, но на как говорят
В теории, разницы между теорией и практикой не должно быть. Но на практике ...Есть объектвиная реальность данная нам в ощущения и документация там «illegal immigrant» по вашей терминологии.
Читателю будет легче, если у интерфейса будет префикс. Точка.Моя точка зрения, что надо следовать принятым практикам, чтобы завтра пришёл новый боец и с достаточной вероятностью он уже знает что, как и где. Для c# это значит префикс «I» перед интерфейсом и префикс «T» перед дженериками. Даже если лично моё чувство прекрасного страдает.
Если же в хаскеле не принято ставить префиксы (не знаю так это или нет), то лучше не надо, даже если сильно хочется.
неудобство человека который раз в полгода что-то посмотрит, с учётом того что он и так язык не знает и ему придётся детально разбираться, может не стоить выгод приобретаемой основной командой
- человека → всех людей, которые заглянут в код
- и так язык не знает → не использует язык в режиме 24/7, знать язык он может лучше автора
- детально разбираться → ровно наоборот, понять структурно и архитектурно
- выгод приобретаемой основной командой → в случае, если в команду не приходят новые люди, все в команде считают это выгодами и вообще — если эта выгода есть.
документация там «illegal immigrant»
Зависит от культуры, сложившейся в сообществе. У нас в уютном мирке эликсира принято соотношение документация ÷ код ≥ 1.0
. Потому что сигнатуры часто недостаточно, чтобы рассказать, как эта функция работает. По сигнатуре не понятно, что, например, случится, если виртуальная машина грохнет этот гринтред из-за переполнения стека его вызовов из других гринтредов.
Для однопоточного перекладывания джейсона это, наверное, оверхед, впрочем.
надо следовать принятым практикам
Не боги камни обжигают. Эти практики придумали такие же люди, как мы с вами. Переучиться нотации можно за два дня, с помощью линтера и звуконепроницаемой комнаты, чтобы коллеги не слышали ваших матов.
Единственное условие — отходить от практик можно только тогда, когда вы умеете объяснить новичкам, почему тут так, и они с восторгом в глазах с вами соглашаются, как согласились до того действующие члены команды.
Но им может потребоваться узнать, как там оно реализовано, для каких-то своих нужд.
Им кроме того интерфейс это или нет надо будет знать еще кучу вещей. И скорее всего, интерфейс это или нет будет не очень важным для такого сценария.
Я тут последние полгода-год пользуюсь idea + intellij-haskell, и оно прям рулит и педалит с точки зрения навигации по коду, включая прыжки в библиотеки.
Вы, блин, с каких пор стали дискутировать с тремя случайными словами, вырванными из контекста? Я, вроде, не на эликсире же написал, а на чистом русском, которым вы прям неплохо владеете: писать хаскель легко, спасибо типам и IDE.
Читать, читать без IDE невозможно. При том, что теоретически IDE для хаскеля — нужна чуть поумнее грепа. Оно не приносит никакой вообще обратной связи, кроме навигации.
В идрисе — да, я никогда даже не пытаюсь понимать хоть сколько-нибудь сложный код с экрана, потому что IDE (на самом деле, компилятор идриса, IDE в этой сделке — просто барыга-перекупщик) мне позволит везде, где я споткнулся — вставить дырку и повторить ход мысли автора.
почему в идрисе или агде нет какого-нибудь хуглоподобного поиска
Потому что не хватает рук? Я близок к тому, чтобы самому этим заняться, как только второй компилятор хоть чуточку стабилизируется и превратится в полноценный LS, как первый — нырну.
Да, согласен. Моё утверждение, что хороший код всегда красивый — неверное. Читабельный и поддерживаемый код всегда красивый. А в случае с перфомансом — часто есть трейдоф между читабельностью и производительностью, и если код критичен к скорости, то он может быть не красивым и при этом хорошим.
Другой вопрос, что критичность по перфомансу — редкость. а вот читать и поддерживать надо всё.
Но код «красивым» назвать язык не повернется. Это сплошной WTF.
Впрочем, времена хакеров ушли, пришли времена нытиков.
Разобрались с префиксами, теперь нам режут глаза фигурные скобки.
Ага, щаз! Я встречал вот такой гибрид:
internal static class SomeClass {
public static void DoSomething(bool arg1, bool arg2) {
if (arg1) {
if (arg2) {
some_precious_code ...;
some_precious_code ...;
some_precious_code ...;
some_precious_code ...;
}
else {
some_more_precious_code ...;
some_more_precious_code ...;
some_more_precious_code ...;
some_more_precious_code ...;
}
}
else {
some_more_precious_code ...;
some_more_precious_code ...;
some_more_precious_code ...;
some_more_precious_code ...;
}
}
}
То есть фигурную скобку оставляем на строке с декларацией, но после неё вставляем пустую строчку. Всё дело в том, что у K&R стиля расстановки скобок есть недостаток в виде того, что распределение пустых мест в коде становится сильно несбалансированным: в районе открывающих скобок код идёт очень плотно, тогда как в районе закрывающих становится разреженным.
Тех, кто экономит пробелы, нужно приговорить к пожизненному расстрелу!
Почему закрывающая скобка стоит не в том же столбце, что и открывающая? Это ж как потом читать что тут где во что вложено?!
Это ж как потом читать что тут где во что вложено?!
Отступы же, которые делаются согласно кодстайлу.
Не нравится мне такой кодстайл…
Или открывающую скобку на новую строку, и чтоб были друг над дргуом, или закрывающую ещё вперёд подвинуть.
В таком виде как-то ни туда, ни сюда…
Эти "нравится" и "не нравится" — вопрос привычке. Вон в Джаве так все пишут.
Согласен. Я и не такое вижу периодически, но моих страданий от этого прибавляется, а потому сам обычно переношу открывающую скобку на новую строку. В отличие от автора поста я воспринимаю это так:
<Заголовок> Mega_function </Заголовок>
{ </отступ от заголовка>
<Полезный код>
a=a+b
</Полезный код>
} </Отступ перед новым "параграфом" кода>
А больше всех я не люблю тех, кто и закрывающую скобку лепит тупо в конец последней строки блока кода. Визуально складывается ощущение, что все что ниже — это тупо одна функция, и если редактор не подсветит где она закончилась, то куча времени уходит на разбор того, что ж тут понаворотили.
В том же варианте, который Вы показали, if'ы, объявления и их содержимое(!) мною при беглом чтении воспринимаются как отдельные «смысловые блоки», что несколько затрудняет и замедляет работу.
Это верно только при условии, что объявления функций и условия занимают ровно одну строчку. Если же объявления многострочные, тогда мозгу приходится дополнительно напрягаться, отделяя объявления от последующих блоков кода. Мне, например, гораздо легче читать код, разбавленный пробелами.
Также у нас ещё есть закрывающие скобки. И вот они все стоят каждая на отдельной строке. И это не всегда приятно.
Кстати, есть новая мода писать ',' в конце последней строки любого перечисления. Я её ненавижу, потому что, после запятой должно что-то идти
Возможность писать висячую запятую (или другой разделитель) полезна, когда нужно переставлять строчки. Для этих же целей в ML-like языках в паттернах разрешают вертикальную черту перед первым шаблоном, иначе рефакторить становится сложнее
А чем не угодила запятая в конце списка?
Это в русском языке после запятой должно что-то быть, а в данном случае это способ "перебздеть", чтоб однозначно было понятно, что имя параметра/переменной/значение элемента массива указано верно и окончательно. Я бы, конечно, какой-нибудь октоторп использовал вместо запятой, но создатели языков программирования решили иначе, а потому имеем что имеем…
Энное количество лет назад я работал под началом прекраснейшего программиста (и посредственнейшего начальника, но да это не имеет тут значения) — этот человек, будучи отягощен высокой должностью и бесконечными совещаниями с вовлечением в процесс управления конторой, иногда просто находил откуда-то время написать немного кода, и решить задачу, которую банально не осиливал решить никто другой. Скажем, за четыре дня выходных запилить наколенный прототип движка MS AS, который мог в агрегацию и представление данных, подключался к базам и потоковым данным, парсил и компилировал MDX (не весь конечно, а самый-самый минимум в виде селекта по многомерным данным и полудюжины самых нужных для прототипирования функций), имел минимально возможную цикломатическую сложность, не жрал лишней памяти, и, главное, имел архитектуру, которая ни разу (пока я еще работал в той конторе, но это много лет) более не переделывалась, так как расширялась везде, где нужно.
Код, который он при этом производил — был, в общем-то абсолютно никакущий. По любым стандартам, даже самым мягким. Там были баги. Там было множество неотработанных edge case. Естественно, там не было Идеологически Верного Нейминга и Форматирования. Тесты там существовали в виде экспериментальных прогонов этого кода в main(). После него, на этот код надо было напустить еще парочку более тупых программистов (типа меня, в те времена я еще немного в Яву мог), которые бы пришли, навели порядок, пофиксили баги, написали бы правильные имена, тесты, и всё вот это. Разница, однако, была в том, что он за четыре дня писал в целом рабочий код, который мы написать за хоть сколько-нибудь обозримое время просто не могли (за бесконечное время конечно бы написали бы, но у бизнеса столько нет) — и этот код приносил неслабые деньги, его, после прилизывания, можно было допиливать до MVP и показывать серьезным дядькам в галстуках и продавать еще не написанные продукты с его использованием за огромные деньги.
Так вот, полезность такого «говнокода» (в кавычках) я не просто мог видеть, но и собственными глазами видел, в форме циферок в долларах с большим количеством нулей справа, отображающихся в публичной финотчётности конторы, спустя квартал после того, как мы это всё облизали и собрали демки.
А вот полезность идеологически вылизанного перекладывателя жсона (или http-запросов, что совсем недалеко ушло) — она мне представляется прямо таки на порядки более сомнительной. Соответственно, оформительские многочасовые страдания над таким кодом — они недалеко ушли от многочасовых оформительских страданий над кодом местячкового локального пет-проекта для конкретной узкой задачи, который заведомо никому не нужен и вообще пишется write once кодом.
Прикольное, но на практике совершенно бесполезное извращение.
Если вам надо переложить пять хттп-запросов — многочасовые страдания над каркасом идеального перекладывателя запросов бесполезны.
Мой опыт показывает, что все эти заморочки с каркасами — это все тоже ерунда. Никогда до этапа активной разработки и использования приложения не получится понять, где нужна гибкость и расширяемость и как именно приложение будет использоваться реальными юзерами. В итоге часы проектирования и вылизывания абстракций обычно в первые же месяцы реальной работы летят в помойку, а поверх них в ковбойском стиле фигачится говнокод. Потому что внезапно оказалось, что реальным клиентам нужно совсем другое и в другом месте.
По этой же причине за нерасширяемые классы я бы голову отрывал. Сколько раз натыкался на то, что мой юз-кейс библиотеки отличается от того, что там было в голове у автора при ее создании. И мне нужен доступ например к протектед-полю. И единственный способ это сделать — отнаследоваться от класса и прокинуть его в паблик. Некрасиво — да, но там блин клиенты ждут и деньги капают. А тут бац — и final класс, и хрен тебе, теперь придется делать еще более кривые костыли (звать через рефлекшн, если это возможно, или просто тупо копипастить код либы в свой класс).
Кстати, есть новая мода писать ',' в конце последней строки любого перечисления.
Зато когда нужно добавить новый элемент, в диффе изменений у вас будет не 1 строка изменена (добавлена запятая) и 1 строка добавлена, а просто 1 новая строка. Это позволит избавиться от лишних конфликтов в этой строке при мерже с мастера в ветку фичи, да и просто, блейм гита будет более правильным.
Да и в целом — код без комментов и «лишних» скобок? Поддержкой видимо тоже не занимается.
Я слышал, что у них есть общепринятый инструмент для стат типизации, нет?
Если вы предлагаете новый стиль кода в готовой экосистеме, на самом деле вы предлагаете смесь из вашего стиля и старого стиля. Потому, что ни стандартную ни сторонние библиотеки не будут переписывать и придется читать смесь.
Значит новый стиль должен принести настолько большое преимущество, чтобы оправдать накладные расходы на смесь. По предложенным пунктам я не вижу такового. Возможно, автор пробовал это делать в команде и все сказали, что так удобнее но упоминаний про это нет и даже про то, когда он так начал писать и каковы результаты этого тоже не написано.
Префиксы и суффиксы теоретически зло, но я буду писать как принято в данной экосистеме, чтобы быть понятным. Ибо зло это небольшое. Суффикс Exception тоже нехорош, так как по названию класса должно быть понятно, что это ошибка (Например InvalidArgument).
Они и должны называться одинаково, это одинаковые по смыслу сущности
Они разные потому, что они не одно и то же. У интерфейса свой контракт, если сильно хочется назвать класс так же как интерфейс или мокать класс, то что-то не то с пониманием чем интерфейс вообще отличается от конкретной реализации и каков его контракт.
Название API кажется странным. Для внешнего потребителя все API. Например строка по такой логике тоже должна называться API. String.API.
Если хочется что-то назвать API скорее всего ответственность данного интерфейса не совсем понята и возможно, даже, что его можно разбить на куски по конкретным ответственностям.
В целом это и есть посыл статьи. Я вижу вещь, которая как принято, она мне не нравится, я начинаю думать — как лучше. И в итоге-то все равно говно какое-то.
Название API — и правда странное, моя ошибка. Должно быть — WebApi, или %Domain%WebApi
тогда мне непонятно, почему это интерфейс, а не неймспейс, и как он может быть у Http клиента менеджер лицензий или это не HttpClient а RestClient? Тогда слово Web должно быть уже внутри слова HTTP.
Скорее всего пользователь сначала определяется какой конкретный API использует, а потом уже оперирует сущностями.
using KingOfDevs.SpecificRest.WebApi;
// если по-вашему а не по стандарту
License.Repository licenses = GetSpecificRestClient().Licenses;
licenses.Remove(myLicense);
Т.е. я бы все эти слова про API вынес бы в контекст определяемый юзингами то, что внутри неймспейса сделал бы максимально похожим на доменный язык.
Можно тоже в холиваре поучаствую? :)
Лично я люблю префиксы для полей классов, потому что они
- Помогают автодополнению — я пишу m_ и сразу же получаю весь список полей; обычно дополнение ориентируется на первую букву, которую я не всегда помню точно.
- Они помогают избегать дурацких проблем с придумыванием имен для параметров в конструкторах или геттерах.
Но вообще, как пишущий на С++, скажу одно — иметь единое соглашение об именах для всего языка (как в C#, например) — это великолепно, вы просто не понимаете своего счастья! Пусть лучше будет неидеально, но зато единообразно.
Я пробовал так делать — и это просто дольше, длиннее и менее удобно. Особенно -> ставить (даже если IDE автозаменяет точку на стрелку, она при этом немножко подтупливает).
Это, разумеется, мои личные ощущения — но и весь пост о личных ощущениях. Почему в целом по языку не принято — судить не берусь, но в С++ вообще туго с единым стилем; может где-то и принято.
С одной стороны, это лишние слова. С другой — никто не заставит так писать везде, компилятор по рукам не надаёт, так что обязательно найдётся кто-то, кто this писать не будет. Получится каша. Префикс в этом отношении лучше, один раз написал, все остальные при использовании его тоже напишут.
- Они помогают избегать дурацких проблем с придумыванием имен для параметров в конструкторах или геттерах.
Проблемы языка, не? В других подобных проблем просто нет:
struct Dto {
id: u32,
name: String,
}
impl Dto {
fn new(id: u32, name: String) -> Self {
Self { id, name }
}
fn name(&self) -> &str {
&self.name
}
}
Проблемы языка, да — но я, к сожалению, не могу просто взять и сменить язык.
Я бы не сказал, что этот пример демонстрирует преимущества раста в экономии на именах переменных. В этом примере как раз показывается, что Rust вначале создаёт сам себе проблему с boilerplate code (тк требует в конструкторе в общем случае указывать имена полей), отсутствующую в C и плюсах:
impl Dto {
fn new(_id: u32, _name: String) -> Self {
Self { id: _id, name: _name }
}
}
И потом героически её решает с использованием сахара под названием field init shorthand, который и применяется в вашем куске кода. 1 — 1 = 0.
Сишный код не требует никаких имён полей:
typedef struct Dto {
unsigned int id;
const char *name;
} Dto;
const Dto make_dto(unsigned int id, const char *name)
{
Dto ret = {1, "abc"};
return ret;
}
Если уж демонстрировать безымянные конструкции раста, то на tuple struct:
struct Dto(u32, String);
fn main() {
let foo = Dto(1, "abc".to_string());
println!("{}", foo.1);
}
В C/C++ подобный способ инициализации (кстати, как он называется) чреват отстрелом ног — порядок можно перепутать, если типы позволяют:
typedef struct Dto {
int foo;
int bar;
}
const Dto make_dto(int bar, int foo)
{
Dto ret = {bar, foo};
return ret;
}
Либо есть designated initializers (C99, C++20):
{.foo=123, .bar=456}
которые возвращают проблему дублирования, о которой вы говорите. Так что, ИМХО, в Rust сделано неплохо.
Мозгу проще и приятнее заниматься этим (а не реальной работой, требующей более сильного напряжения творческих сил), это вроде бы установленный медицинский факт.
Фантастическая (но реализуемая, и не слишком сложно) идея — иметь локальную конфигурацию «идеального» форматирования и схемы наименования кода, плюс наиболее популярные вариативные проекции в repo для поиска на любой вкус.
Пример реализации: автор(ы) языка Nim забил(и) (в основном) на различия CamelCase snake_case nocase bAdCaSe в наименованиях. Хороший пример послать паразитную проблему подальше, не идеальный (в идеале в проекте есть спеллчекер в идентификаторах и правильная конверсия в CamelCase, snake_case, nocase по настройкам индивидуального разработчика — плюс строгое выпалывание bAdCaSe, конечно).
Слабое место — поиск, но это технически решаемая проблема. Интересный комментарий выше — про полезность минимального Hungarian вроде "_" или «m_» префиксов, теперь уже из-за удобств IDE. С чего я начну новую строку моего идеального кода? Первый элемент намеренья обозначен довольно рудиментарным префиксом, а там уже — любимая мозгом рутинка, как в компьютерную игрушку играешь. Все довольны (главное, мозг :) ).
Любая система так работает. Её эффективность определяется самым слабым звеном. К системам, состоящим из людей, это тоже относится. Поэтому у того, кто владеет/управляет системой в целом, базовая задача состоит не в том, чтобы прокачать один из компонентов на максимум эффективности, а в том, чтобы все компоненты работали более-менее средне. С помощью формальных правил самых слабых можно подтянуть до среднего уровня, а самых эффективных, наоборот, опустить.
Зависимость от очень эффективных в большом проекте никому не нужна. Таким людям нужно работать в стартапах. Это как с ценами на нефть. Кажется, что высокие цены — это хорошо. Но если привыкнуть к высоким ценам, то будет очень плохо, когда они существенно снизятся. Это простейшая задача на управление рисками. И решение у неё только одно — не привыкать к хорошему. На уровне всех бизнес-процессов всё хорошее должно приводиться к обычному.
Мне важно насколько много кода ты увидишь в одном экране. В этом плане я настоящий идеалист — если файл с кодом требует больше одного моего экрана (он у меня довольно мелкий), я делаю всё что могу, что бы его сократить.
Одна из причин, почему я не смог пользоваться райдером — это остутствие функции/экстеншена Shrink Empti Lines https://marketplace.visualstudio.com/items?itemName=VisualStudioPlatformTeam.SyntacticLineCompression
Абсолютный мастхэв, без которого использование места на экране кажется варварством.
Со многим согласен, хотя пишу на PHP. Любимый стайлгайд — Doctrine. В нём, например запрещены суффиксы/префиксы interface/exception/abbstract. Почти не могу представить ситуацию, когда они важны, кроме интерфейса или абстрактного класса с единственной реализацией.
но я за постфикс `Exception`
Чуть менее чем все использования SomeThingException помещаются в два кейса:
catch(SomeThingException ex)
и
throw new SomeThingException()
То есть по окружению легко понять, что ты имеешь дело с эксепшенами, фтопку постфиксы ;-)
Кстати ведь да
outcome switch
{
{ NotFound: { code : 404 } } => ...,
{ NotAllowed: { role : "Admin" } => ...,
};
Чё-как, кто тут эксепшон?
Пха. «Король разработки». Неужели я таким же был, кхм… «Королём»…
А тут проблемы с платформой — в C# с моками всё очень плохо — если захочешь делать мок не на интерфейс, а на класс с не виртуальными свойствами и методами — пойдешь в жопу.
Это не проблемы, это хорошо. Я видел код на Python (в котором можно мокать почти всё), в котором для тест кейсов описывали штук пять-десять декораторов unittest.mock.patch (которые подменяют класс/метод на мок-объект), в том числе, мокающие некоторые приватные функции модуля при тестировнии его самого. Я вообще не уверен, что такой тест способен что-то отловить. Особенно, если учесть, что у питона динамическая типизация и даже изменение сигнатур зависимостей мы не заметим (они же замоканы!). mypy есть, но помогает не всегда.
Моя война с большими файлами продолжается — я строго против xml-документации. Она всегда уродует код, иногда делает понятнее хреновый код, иногда дублирует информацию, представленную хорошим кодом. Братан, у тебя есть имя неймспейса, имя класа, имя метода. Имена параметров. Их типы, и имена этих типов. Если всех этих вещей тебе мало, что бы объяснить, как мне использовать твой код, документация тебе не поможет. Она просто замаскирует твою некомпетентность.
Желаю автору почитать MSDN без текстов, с одними лишь именами функций и параметров.
Что в программировании важнее всего?
Знать структуры данных. Отсортированный массив — это структура данных. Граф — структура данных. Совмещаем их и получаем сложную структуру данных — базу данных, индексацию, отношения. От неё зависит то, как будут написаны алгоритмы.
Структуры данных — это фундамент любого знания программиста. Если ты их хорошо знаешь, то можешь работать где угодно и за любую зарплату. Низкоуровневое программирование, сайты, игры, дата саенс — всё основано на структурах данных.
Популярно говорить о том, что «код нужно писать для людей». Так вот люди лучше работают с подходящими для решения структурами данных. Плохо спроектированное API с гениальными названиями переменных не сделает проект лучше. Названия переменных, язык, типизация, практики — всё это уходит на второй, третий, четвёртый, пятый план.
Метафизически, существует только одна реальность — та, которую мы воспринимаем. Структуры данных — это концепции, основанные на правильном, непротиворечивом, логическом восприятии реальности.
Выбить структуры данных из основ любого знания программиста — это означает отказаться от реальности, начать созерцать ноль и писать поэтические книги о том как красив этот ноль.
Нет, это относится не только к средневековым монахам. Таким образом я вижу эту статью.
Вам может стать плохо от того, какую громадную неразборчивую систему возвёл автор. Автор упоминает: последние версии ПО, экспериментальные фичи, выбор IDE, как назвать интерфейс, как избежать длинных названий, принятые конвенции по именованию, обвинение конвенций, другие сервисы по работе с кодом (гитхаб), проблемы моков, сравнение C# с F#, оформление скобок, посторонняя мысль о красоте кода, посторонняя мысль о тайпскрипте и фронтенде, зрительное восприятие кода, заметка о привычках, размышление об абстракциях, xml-документация, многострочный код, префиксы, мода на запятые…
Предложения, под-предложения, под-под-предложения, упоминание всего что только придёт в голову, ссылки на реальные знания о программировании, на псевдо-знания, выбрасываемые в случайном порядке, основанные на единственном строительном элементе: отсутствие определений. Это интеллектуальный яд, который парализует мышление.
Между тем, вывод кристально чист. Автор делает программирование такой областью, которой невозможно заниматься.
Если вы хоть раз задавались вопросом: «Почему я не получаю удовольствия от программирования?» — обратите внимание на ту статью. Мозг, оторванный от реальности, не способен испытывать удовольствие.
Подобного рода атаки направлены на тех людей, кто не относится серьёзно к идеям. Они сдаются в разум другого человека также, как сдаются в запутанность и сложность какой-либо программы. Они не переступают порог концептуального знания и принимают его как за данность, как за явление природы. Те, кто это знают, наживаются на этом.
Для того, чтобы уметь отражать эти атаки, нужно быть первоклассным философом. Подобно тому как программист может стереть плохую программу, первоклассный философ может стереть миллионы бессмысленных слов. Моя статья не является руководством о том как таким стать. Для этой цели я могу порекомендовать книгу “Introduction to Objectivist Epistemology.”
Здесь коротко написано о чём эта книга: https://aynrand.org/novels/introduction-to-objectivist-epistemology/
Эта книга помогла мне вернуть фокус в области программирования с нео-мистиков из примера выше к реальности. Надеюсь она поможет и вам.
“Человек ни непогрешимый, ни всезнающий; если бы он был таковым, такая дисциплина как эпистемология... не была бы ни необходимой, ни возможной:... Человек является существом волевого сознания; за гранью уровня восприятий – уровня неподходящего познавательным требованиям для его выживания – человек должен получить знание своими собственными усилиями, которые он может выполнять или нет, и процессом разума, который он может применять правильно или неправильно. Природа не даёт ему автоматической гарантии его ментальной способности; он способен на ошибки, упущения, психологическое искажение. Ему нужен метод познания, который он сам должен открыть: он должен открыть как использовать его рациональную способность, как подтвердить свои выводы, как отделить истину от лжи, как установить критерий что он может принять за знание.”
Я стал думать над мелочами в коде, и уничтожил все желание программмировать