Здравствуйте, no_ise, Вы писали:
_>Это у Autodesk то внутри мамонтообразного кода нет?
В старом коде — есть, в новом коде активно борятся вполть до выкидывание целых кривых подсистем и переписывания с нуля.
_>Ага Да, у Хофштадтера, кажется, было: медианы не существует.
А еще где-то было "чукча не читатель, чукча писатель", только не помню кто сказал
Здравствуйте, kaa.python, Вы писали:
KP>Здравствуйте, no_ise, Вы писали:
_>>Это у Autodesk то внутри мамонтообразного кода нет?
KP>В старом коде — есть, в новом коде активно борятся вполть до выкидывание целых кривых подсистем и переписывания с нуля.
Я не сторонник нечитаемости и нерасширяемости. К тому же, уже безотносительно Autodesk, нечитаемость и нерасширяемость
встречаются двух сортов (все реже и реже, что не может не радовать)
а) Код написанный, скажем, в 2000-х и настолько чудесно запроданный за 20 лет, что это уже священная корова,
которая кормила и поила все переписывания, слияния-поглощения, яхты и новые отделы.
б) Чей-то mortgage code.
_>>Ага Да, у Хофштадтера, кажется, было: медианы не существует.
KP>А еще где-то было "чукча не читатель, чукча писатель", только не помню кто сказал
Всех не упомнишь В смысле, что вряд ли так просто получится устаканить определение "обычной компании".
Если по всем критериям усреднить то скорее всего какая-то "необычно серая компания" получится.
PD>>А если бы его не было, то получилось бы нечто вроде
PD>>
PD>>List<String> list = makeStringList(sorted(filter(users)));
PD>>
KP>А вот что-то вроде уже бы предложили переписать
А что тут нечитабельного и непонятного ? Только то, что порядок действий справа налево и вместо точки используются круглые скобки ?
Прочие-то аргументы ТС (побочные эффекты) тут не проходят — они одни и те же.
x = *s &~ *m;
if (x) {
if (x & SYNCHRONOUS_MASK)
x &= SYNCHRONOUS_MASK;
sig = ffz(~x) + 1;
return sig;
}
switch (_NSIG_WORDS) {
default:
for (i = 1; i < _NSIG_WORDS; ++i) {
x = *++s &~ *++m;
if (!x)
continue;
sig = ffz(~x) + i*_NSIG_BPW + 1;
break;
}
break;
case 2:
x = s[1] &~ m[1];
if (!x)
break;
sig = ffz(~x) + _NSIG_BPW + 1;
break;
Все понятно ? Беретесь сопровождать после 10 минут знакомства с этим кодом ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Все понятно ? Беретесь сопровождать после 10 минут знакомства с этим кодом ? PD>Или тоже объявите это говнокодом ?
Самую малость причесать (первый раз вижу чтоб A & ~B писали как A &~ B) и нормально.
Здравствуйте, CreatorCray, Вы писали:
CC>Самую малость причесать (первый раз вижу чтоб A & ~B писали как A &~ B) и нормально.
Напиши автору
Но ты не ответил на вопрос. Код действительно понятен ? Вносить изменения будет легко ?
Или надо было его разбить на несколько функций, дать имена из 10-15 символов и сделать так, чтобы интуитивно были понятны все эти "++s &~ *++m" и т.п. ?
Я себе представляю, что бы тут завопили, если бы я представил код с несколькими однобуквенными именами и методом с именем ffz для бизнес-приложения. И правильно бы завопили.
Я все это к тому же самому — разный бывает код и разные задачи.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Напиши автору
Зачем? Верховного пЫнвина уже не перевоспитаешь
Но он хоть старается писать просто.
PD>Но ты не ответил на вопрос. Код действительно понятен ? Вносить изменения будет легко ?
С бОльшего понятен. Немного простого рефакторинга и будет совсем хорошо.
PD>дать имена из 10-15 символов
Имена надо давать внятные а не из "10-15 символов".
Но такой код очень легко превращается в удобночитаемый через refactor rename, структуру там не надо править.
PD>Я себе представляю, что бы тут завопили, если бы я представил код с несколькими однобуквенными именами и методом с именем ffz для бизнес-приложения. И правильно бы завопили.
Имена поправить проще чем вывихнутую логику.
Здравствуйте, CreatorCray, Вы писали:
PD>>Но ты не ответил на вопрос. Код действительно понятен ? Вносить изменения будет легко ? CC>С бОльшего понятен. Немного простого рефакторинга и будет совсем хорошо.
Да и так вроде неплохо. Работает на всех Дебианах, Убунтах и прочих Редхетах уже не один десяток лет.
CC>Имена надо давать внятные а не из "10-15 символов".
Одно другому противоречит ? Однобуквенные имена внятные только если это переменные из математики или физики. Не удосужились там до сих пор давать переменным многобуквенные имена, так и пишут v = s/ t и всем понятно. Ну а в том примере, что такое s, x и m — мне так не очень понятно.
CC>Но такой код очень легко превращается в удобночитаемый через refactor rename, структуру там не надо править.
Ох, что-то я сомневаюсь, что "++s &~ *++m" станет намного понятнее, если заменить s и m на что-то иное с помощью refactor rename.
PD>>Я себе представляю, что бы тут завопили, если бы я представил код с несколькими однобуквенными именами и методом с именем ffz для бизнес-приложения. И правильно бы завопили. CC>Имена поправить проще чем вывихнутую логику.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да и так вроде неплохо. Работает на всех Дебианах, Убунтах и прочих Редхетах уже не один десяток лет.
Машине всё равно. Код рефакторится для понимания его человеком.
PD>Однобуквенные имена внятные только если это переменные из математики или физики.
Применительно к программированию — нет, ибо там есть много букв вообще не из латиницы. Не, ну их уже конечно можно набрать но гемору просто море.
Однобуквенные переменные ОК если это очевидный индекс в каком нить не очень большом и локальном цикле.
PD> Ну а в том примере, что такое s, x и m — мне так не очень понятно.
Ну т.е. ты в итоге со мной согласился что "Имена надо давать внятные"
PD>Ох, что-то я сомневаюсь, что "++s &~ *++m" станет намного понятнее, если заменить s и m на что-то иное с помощью refactor rename.
Если ещё и ++ вынести отдельно то станет ещё чуток понятнее. Но в целом уже ок, тут ничего от глаза не прячется.
PD>Логика, я думаю, тут в полном порядке.
Тут да. Я имел в виду вывихи в других примерах.
Здравствуйте, CreatorCray, Вы писали:
CC>Машине всё равно. Код рефакторится для понимания его человеком.
Верно, но при условии. что этот человек может разобраться в такого рода коде.
CC>Однобуквенные переменные ОК если это очевидный индекс в каком нить не очень большом и локальном цикле.
А также если это математический или физический расчет и есть общепринятые обозначения
double x = -p/2 + sqrt(p*p/4 - q)
лучше чем что-то иное.
PD>> Ну а в том примере, что такое s, x и m — мне так не очень понятно. CC>Ну т.е. ты в итоге со мной согласился что "Имена надо давать внятные"
Но я и не собираюсь разбираться в этом коде. Так что согласился только в рамках, скажем, бизнес-приложений, но тут я и не возражал. В других случаях понятность может определяться иначе или вообще быть не главным, так как все равно непонятно без серьезного описания, возможно, с картинками. Например, математические алгоритмы
Несомненно, тут можно претензии предъявить к коду, да и вообще это перевод с Алгола алгоритма из книги, которой я пользовался еще в молодости.
Да, можно код причесать. Но никакой заменой имен этот код понятнее не сделать — для этого надо хорошо понимать сам алгоритм.
Более того. Книги этой у меня под рукой нет, проверить не могу, но скорее всего описание алгоритма там дано с использованием этих u,v,d,b,z. И гораздо лучше, если они в программе и используются — читающему не хватает только в голове держать map от имен в книге на имена в программе
Так что опять же — в разных случаях разные требования.
Мое мнение — ты взял, в общем-то, вполне разумное требование к коду : код должен быть понятным. Я и не спорю с этим. Разница между нашими точками зрения в том, что для тебя эта максима, нарушение которой никогда не возможно и ведет в геенну огненную. Для меня это лишь одно из требований к коду, которое может быть первоприоритетным, если нет других, более существенных в данном случае требований.
Здравствуйте, Pavel Dvorkin, Вы писали:
CC>>Машине всё равно. Код рефакторится для понимания его человеком. PD>Верно, но при условии. что этот человек может разобраться в такого рода коде.
Пардон, но если человек не в состоянии разобраться в коде то всё, тушите свет и сливайте воду — он ничего с этим кодом не сможет сделать в любом случае.
Рафакторинг же запутанного кода таки помогает и разобраться и привести его в более человекочитаемый вид.
PD>Разница между нашими точками зрения в том, что для тебя эта максима, нарушение которой никогда не возможно и ведет в геенну огненную.
В общем неверно. Не очень понятно с чего ты взял про максиму и прочие ацкие спецэффекты.
Но я прекрасно знаю цену плохому коду. Так что если это не одноразовое написал-запустил-выбросил то надо стараться писать как можно более чисто. Плохо само получится.
Так что код публично доступной библиотеки должен быть вычищен от копролитов и хорошо документирован.
PD> Для меня это лишь одно из требований к коду, которое может быть первоприоритетным, если нет других, более существенных в данном случае требований.
Верно, но в рассматриваемых примерах нет совершенно никаких "других, более существенных в данном случае требований", которые бы оправдывали небрежность, которую мы там наблюдаем.
Здравствуйте, Pavel Dvorkin, Вы писали:
CC>>Но такой код очень легко превращается в удобночитаемый через refactor rename, структуру там не надо править.
PD>Ох, что-то я сомневаюсь, что "++s &~ *++m" станет намного понятнее, если заменить s и m на что-то иное с помощью refactor rename.
Будет лучше, причём значительно. Во-первых, s и m можно назвать. Хуже от этого точно не станет. Вообще не понимаю — какой смысл называть переменную одной буквой, что именно экономится при этом?
Во-вторых, там не ++s, а s с разыменованием. И это вообще не интуитивно. Это не олимпиада по знанию приоритетов операций, код должен читаться легко. Надо явно создать переменные и их назвать. И да, выделить 100500 функций, которые пояснят что именно происходит.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А также если это математический или физический расчет и есть общепринятые обозначения
PD>
PD>double x = -p/2 + sqrt(p*p/4 - q)
PD>
PD>лучше чем что-то иное.
Не лучше. Я не понимаю, что здесь происходит. И вообще не факт, что я не буду следующим, кто будет вынужден этот код поддерживать.
И будет сильно лучше для всех, если этот код будет выглядеть так:
PD>
В целом это похоже на создание касты "для тех кто понимет, что здесь происходит".
Математики тоже могут так загадить код, что потом сами перестанут понимать что происходит и где какая известная для них функция используется. И наверняка эта формула там не один раз встречается. Если где-то есть ошибка, то её надо будет искать везде.
Если захочется поменять формулу по каким-то причинам, то тоже придётся её везде искать, вместо того, чтобы исправить в одном месте.
Здравствуйте, alzt, Вы писали:
PD>>А также если это математический или физический расчет и есть общепринятые обозначения
PD>>
PD>>double x = -p/2 + sqrt(p*p/4 - q)
PD>>
PD>>лучше чем что-то иное.
A>Не лучше. Я не понимаю, что здесь происходит. И вообще не факт, что я не буду следующим, кто будет вынужден этот код поддерживать. A>И будет сильно лучше для всех, если этот код будет выглядеть так:
PD>>
A>double someFuncWithClearName(double p, double q) {
A> return -p/2 + sqrt(p*p/4 - q);
A>}
PD>>double x = someFuncWithClearName(p, q);
PD>>
A>В целом это похоже на создание касты "для тех кто понимет, что здесь происходит". A>Математики тоже могут так загадить код, что потом сами перестанут понимать что происходит и где какая известная для них функция используется. И наверняка эта формула там не один раз встречается. Если где-то есть ошибка, то её надо будет искать везде. A>Если захочется поменять формулу по каким-то причинам, то тоже придётся её везде искать, вместо того, чтобы исправить в одном месте.
Хороший пример, на нем как раз можно продемонстрировать, что в разных случаях возможны разные решения.
Дело в том, что твоя someFuncWithClearName вычисляет только x1. А еще есть x2, вычисляемый почти по той же формуле.
Делать 2 штуки someFuncWithClearName1 и someFuncWithClearName2 довольно глупо — зачем деление и sqrt 2 раза производить ?
Делать одну someFuncWithClearName с дополнительным параметром типа boolean, например — можно, но будут лишние if и опять же 2 раза вычисление sqrt. И понятнее не будет, скорее наоборот.
Делать метод, который вернет их оба — можно, но результат будет типа какой то pair или tuple, а это скорее всего класс, и значит, выделение памяти в куче, boxing и потом unboxing, что тут вообще-то совсем ни к чему.
И наконец, что если в каком-то месте мне нужен только x1, а x2 совсем не нужен ? А в другом только x2, а x1 не нужен ? Лишнюю работу выполнять незачем, и будет это не понятнее, а наоборот — придется объяснять в виде комментария, зачем мы возвращаем то, что нам не нужно.
Так что все зависит от ситуации. Если это делается в самых разных местах, и всегда нужна пара, и нет проблем из-за boxing — может и стоит сделать какой-то метод. А иначе лучше просто написать
double t = -p/2;
double s = sqrt(t*t-q);
double x1 = t+s;
double x2 = t-s;
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Дело в том, что твоя someFuncWithClearName вычисляет только x1. А еще есть x2, вычисляемый почти по той же формуле. PD>Делать 2 штуки someFuncWithClearName1 и someFuncWithClearName2 довольно глупо — зачем деление и sqrt 2 раза производить ?
Зависит от ситуации. В большинстве случаев — да. Это реально ни на что не влияет. Если это проект, где нужна скорость и есть бенчмарки, которые показывают, что 2 раза вычислить квадратный корень нельзя, тогда это не подходит. Но в большинстве случаев это будет преждевременной оптимизацией. Тормозить по факту будет что-то другое.
PD>Делать одну someFuncWithClearName с дополнительным параметром типа boolean, например — можно, но будут лишние if и опять же 2 раза вычисление sqrt. И понятнее не будет, скорее наоборот. PD>Делать метод, который вернет их оба — можно, но результат будет типа какой то pair или tuple, а это скорее всего класс, и значит, выделение памяти в куче, boxing и потом unboxing, что тут вообще-то совсем ни к чему. PD>И наконец, что если в каком-то месте мне нужен только x1, а x2 совсем не нужен ? А в другом только x2, а x1 не нужен ? Лишнюю работу выполнять незачем, и будет это не понятнее, а наоборот — придется объяснять в виде комментария, зачем мы возвращаем то, что нам не нужно.
Это означает, что пора создавать класс, который будет иметь функции someFuncWithClearName, someOtherFuncWithClearName и т.д. и кешировать свои данные, чтобы этот корень дважды не вызывался. А может вообще пора наплодить интерфейсов, написать фабрик и декораторов. И я не утрирую и не иронизирую. Зависит от ситуации, но почти всегда это будет лучше, чем то, что было описано выше. Потом менять что-то будет сильно проще. И не обязательно брать какого-то волшебного человека, который в этом разбирается, досаточно просто обычного программиста.