Pull to refresh
73
0
Дмитрий @depp

User

Send message
Более того, лидер показывает результат всего на 20% лучше, чем example.js
Конечно, при реальных переговорах, 20% в денежном выражении совсем не мало, но от конкурса алгоритмов интуитивно ожидаешь большего результата
Скажите, это, стало быть, любую стенку можно так убрать? Вашему изобретению цены нет! (с)
Ну, понимаете, это примерно как вопрос о том, стоит ли читать художественную литературу в оригинале, или достаточно ознакомиться с подборкой «кратких изложений».

Любая мысль, сформулированная в словах, уже теряет часть первоначального смысла, поэтому зачастую бывает полезно ее выразить в двух-трех различных формулировках, чтобы зацепить различные ассоциативные слои в мозгу читателя.

А базовых мыслей/идей в тексте больше чем одна, отсюда и объем.

Я не к тому, что данный текст прям идеален и является образчиком изложения, но все-таки бОльшая часть слов в нем использована не просто так, на мой взгляд.
Текст вполне внятный
Большинство программистов значительно больше интересует процесс программирования, чем пользователи, для которых пишется программа, и тем более чем другие программисты, которые потом будут ее поддерживать. А должно быть наоборот )

Можно написать 10 тысяч строк кода на Java, чтобы смоделировать изначально кривой и нестабильный бизнес-процесс, или пользовательский сценарий например, а можно поправить процесс или сценарий и вообще обойтись без написания кода. Но для этого надо выйти за рамки IDE и вообще за рамки представлений о программисте, как о том-кто-пишет-код.

Действительно хороший программист — он как Нео в Матрице, программирует мир вокруг себя, а не программы. Для этого даже не обязательно знать языки программирования :) Об этом и статья

Вот теперь, после вашего комментария, он вобьет эту строчку в гуглояндекс (во время скайп собеседования) и выдаст чужой ответ за свой
Можно начинать придумывать новый пример :)
ОК, давайте по порядку:
1. Насчет договоренностей в команде — вопросов нет, можно договориться хоть в LISP-стиле писать, если это нужно для решения задачи. Только помимо членов вашей команды есть еще масса людей, которые могут ваш код читать потом — если результат вашей работы передается дальше как часть большого проекта, если вы пишете общую либу, если вы используете ваш код в качестве примеров в документации, докладах или вот в статье на хабре. Ну или вот вы написали все прекрасно, сдали заказчику, потом решили чем-то другим заняться, а через 3 года ему другая уже команда должна доработать это все. Возможно за другие деньги совсем. Я понимаю что как программисту вам на это пофиг, но это не значит, что так надо делать. Есть еще такое слово как ответственность.

2. Не надо, пожалуйста, валить в кучу тернарные операторы, побитовые операторы, а также (это к комментарию от RubaXa выше) замыкания, области видимости и т.д. У вас какой-то бинарный программист получается — он либо знает только if-else и все (видимо только вчера basic изучил в школе), либо знает и активно использует все операторы и конструкции языка, которые в нем только есть. Это крайности.
Если посмотреть объективно, то можно выстроить некоторую шкалу встречаемости различных конструкций в коде (в любом JS коде, усредненно), где var-if-else-for будут на первых местах где-то, замыкания и тернарники на 5-10, а побитовые операторы и возврат значения после запятой (return expression, bar) — на 100 по частоте использования.

Опять же, если вы действительно пишите какой-то математический алгоритм или активно работаете с числами, можно и нужно использовать побитовые операторы. Они для этого и сделаны в таких языках как JS. Но без реальной нужды их лучше не вставлять в код, если вы не пишете just for fun и только для себя.
К rock и RubaXa у меня вопрос — вы веб программистов нанимали когда-нибудь на работу? собеседование проводили? искали подрядчиков на аутсорсе? какой процент из соискателей (или потенциальных исполнителей) готов сходу разобраться в ~indexOf или разглядеть XOR оператор в (ret ^ not)? и за какие деньги они готовы потом работать?

а то у меня ощущение что мы с разных точек зрения на это смотрим
Приравняйте «экзотические» к «редко используемые», и ответ найдется сам собой. Усредненный «JS программист в вакууме» за 3, например, года своей карьеры с такими конструкциями может сталкиваться пару раз, даже с учетом кода сторонних плагинов и библиотек. Не надо только говорить, что такому в программировании не место, что надо развивать кругозор и т.д. — по состоянию рынка труда на текущий день у нас таких спецов все равно большинство, и это надо всегда учитывать при написании кода.
Естественно reduce не так быстр, как плоский цикл, не говоря уже о том, что конкретно для uniq$viaReduce в момент вызова indexOf будет перебираться весь массив в поисках нужного элемента, что раздувает количество шагов цикла в квадрат раз.

Однако, все это может быть совершенно не заметно на массивах размером до, например, 1000 элементов (ну или 10 000, я не знаю). Т.е. разница в несколько десятков миллисекунд, либо меньше.

Очень странно слышать комментарии про фигурные скобки и разнесение ветвей на разные строчки в контексте обсуждения
return (~ memo.indexOf(item) ? null : memo.push(item)), memo;

Т.е. понятно, что это чисто синтетический пример, но я и про свой код могу то же самое сказать.

Основная моя претензия была (и есть) к слову, которое вы еще раз употребили в этом комментарии — «джедайский», и смысл которого в контексте приведенного фрагмента кода мне не понятен. Этот фрагмент просто плохой по всем параметрам, т.к. привносит излишнюю сложность для чтения и изменения, которая не компенсируется вообще ничем — ни лаконичностью (мой пример короче), ни скоростью выполнения, не уменьшением количества языковых конструкций. Ничего из этого в коде нет.

И комментарий я написал именно ради того, чтобы этот ваш термин не вводил никого в заблуждение.
Ну в том и смысл, что до приведения типов дело не доходит, когда мы сравниваем заведомо два числовых значения.
Предлагаю не обсуждать дальше разницу в поведении === и == в общем случае — все это давно обсуждено и всем известно. Я специально указал в первоначальном своем комментарии, что он относится только к конкретному фрагменту кода и ни к чему больше.
Ну, на вкус и цвет…
На мой субъективный взгляд "-1" выглядит чуть более «магическим» числом чем «0», для тех кто не знает, что в точности должен возвратить indexOf в случае отсутствия элемента в массиве.
Только в данном случае ===-1 не надо, достаточно == -1
Ведь метод indexOf нам заведомо (согласно спецификации) не может вернуть ничего кроме числа, поэтому нет нужды в дополнительной проверке типа.
Когда я вижу такой код
return (~ memo.indexOf(item) ? null : memo.push(item)), memo;
— хочется обратиться ко всем начинающим (или «продолжающим») JS разработчикам — не пишите так никогда. Совсем никогда. Вы можете подумать, что это какой-то крутой, «джедайский» код — который позволяет очень лаконично выразить вашу бизнес-логику, используя доступные только «гуру» «экзотические» операторы и конструкции.
Это абсолютно не так.

Сравните
return (~ memo.indexOf(item) ? null : memo.push(item)), memo;
и
if(memo.indexOf(item) < 0) memo.push(item); return memo;


Второй вариант на порядок читабельнее, не использует ничего кроме банального if, и (вот где профит-то :-)) — короче на 6 символов.

Он же в виде целой функции, чтобы можно было сразу проверить работоспособность (перенос строки перед return — по желанию)

function uniq$viaReduce (array)
{
    return array.reduce(function (memo, item)
    {
        if(memo.indexOf(item) < 0) memo.push(item); 
        return memo;
    }, []);
};
Есть разные специализации frontend-программистов.
Если нужен «продвинутый» верстальщик, способный к HTML каркасу прикрутить 3-4 плагина jQuery и вывалить с их помощью результат пары ajax запросов — можно не знать разницу между call и apply.
Если надо писать что-то с нуля, разрабатывать API, полностью кастомный UI и т.д. — нужно знать все упомянутое в статье и еще много чего сверху.
Зачем вы мне пишите то, о чем я сам писал в соседней ветке обсуждения habrahabr.ru/post/206868/#comment_7133274 в ответ на ваш же комментарий?
Мне начинает казаться, что я сам с собой веду беседу :)

Если резюмировать мое мнение по этому вопросу — дубликаты всегда выносим в функцию/метод, т.к. проблем от проверки мест вызова функции меньше, чем от проверки изменений и возможных ошибок при несогласованном изменении дубликатов. А если у нас неповторяющийся кусок кода, который теоретически можно обособить и спрятать за абстракцией в виде функции — серьезно подумаем, стоит ли это делать, т.к. в этом случае выигрыш далеко не столь очевиден.
Почитал. Согласно терминологии статьи, при удалении дубликатов мы повышаем «структурную сложность», зато сильно понижаем «количественную» и «сложность изменений» (нет проблем с несогласованной правкой дубликатов), а также частично «алгоритмическую сложность» (за счет вынесения дублирующихся частей алгоритмов в абстракции в виде функций и методов). Моя субъективная оценка — оно того стоит, т.к. сумма трех понижаемых сложностей выше, чем одной повышаемой. В итоге общая сложность проекта уменьшается.
У вас может быть другая субъективная оценка. Доказать свою правоту математически, измерив количественно повышение/понижение сложности, я не берусь.
Насчёт методов из трёх строк. Всегда (почти) предпочту метод из трёх строк методу из 20. Чаще всего, когда ты читаешь чей-то код, ты пытаешься понять смысл того, что делает этот код, а не детализированную имплементацию, поэтому, если программист писал множество мелких функций, то функции верхнего уровня читаются действительно как «хорошо написанная проза», а если нужны детали — всегда можно заглянуть в детали.
У меня вот наоборот как-то получается — понять смысл написанного обычно просто, а дальше нужно в коде что-то поменять, потому что мы его не ради развлечения же читаем, а с какой-то целью. И вот на этом этапе — слишком много маленьких методов и функций создают проблемы, т.к. надо в каждую заглянуть и потом еще половину из них поменять. Что тянет за собой кучу зависимостей из тех мест, где эти функции еще используется. Либо надо все выкидывать и переписывать метод заново.
Поймите правильно, я не за методы по 100-500 строк, которые пытаются делать все на свете. Но и не за методы, в которых вызывается 30 других методов, которые внутри себя вызывают еще в сумме 50-100 функций по 1-3 строки. Я за разумную середину.
Я поясню насчет функции — в том примере который вы привели, типа array_sum, конечно можно и нужно выносить, т.к. это универсальная, библиотечная по сути функция. И как раз маловероятно, что она будет использована только один раз во всем приложении.
Речь про неповторяющийся кусок бизнес-логики, который специфичен для того конкретного участка кода (функции, метода, не важно), который мы пишем/читаем в данный момент. И проблема с функцией в том, что она обычно (хотя зависит от языка конечно) имеет глобальную область видимости. Соответственно, если мы оформляем фрагмент в функцию, мы автоматически создаем вопрос для читающего код — а где эта функция еще используется? Если мне надо ее поменять, не сломается ли программа где-нибудь еще? Конечно, есть IDE, тесты и т.п., но эту проблему можно просто не создавать, чтобы потом не приходилось ее решать.

Насчет двух функций — то же самое, нам надо устранять дублирование, а не просто переносить его в другое место. Было 2 похожих куска кода, стало 2 похожих функции — смысл?

Насчет тернарного оператора — я не первый раз уже слышу про то, что какой-то там средний программист не может это прочитать и воспринять, и каждый раз тихо фигею. Это что, какой-то «know how» прием или хакерский финт — тернарный оператор? Или все-таки стандартная задокументированная конструкция языка? Такие тезисы мне напоминают разговоры пятилетней давности о том, что «у пользователя в браузере может быть отключен яваскрипт». Может быть отключен, да, только он тогда не сможет 90% сайтов пользоваться, и это — нормально.

P.S. За лайфхак кстати спасибо, сыну в школу идти через полтора года, опробую на нем.
Я тут писал уже habrahabr.ru/post/206868/#comment_7129502 — правильное устранение дубликатов не усложняет код. Если у вас есть конкретный пример кода, где устранение дубликатов может привести к неоправданному усложнению — можете сюда выложить или ссылку дать. Вместе подумаем над этим, в качестве разминки для мозга.
Джеки Чан привык по жизни все делать качественно, решил и в новой для себя отрасли сразу разобраться, что к чему.
Ну вообще в статье шла речь про код в рамках одного проекта, а в вашем случае это скорее «подключаемая библиотека» (использую такой термин, чтобы не привязываться к конкретному языку), если код одинаков, либо просто «повторное использование наработанного решения», если он все-таки отличается в разных проектах. Если же подключение библиотеки приводит к проблемам типа Dependency_hell, то это уже не к коду вопрос, и решать его надо на другом уровне.
Понятное дело, если всю систему за пару дней не изменить, а релиз завтра — можно просто скопировать код, да. Но надо помнить, что можно сделать лучше.
1
23 ...

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity