3237

Ответ на пост «Современное програмирование»3

В 2016 году, один человек удалил библиотеку на 11 строк кода и половина веб приложений попадало. Это был Альберт Э... э нет. Это была библиотека left-pad:

Очень многие используют Реакт. Реакт использует библиотеку, которая использует библиотеку... ...которая использует библиотеку, разраб которой был очень ленивый и не захотел сам писать очень простую функцию на 11 строк. И он решил использовать left-pad. Эта библиотека просто добавляет символы в начало строки.

Например:

leftPad(17, 5, 0) вернет "00017".

leftPad('ikabu', 8, 'p') вернет "pppikabu".

И все бы было хорошо, но разработчик left-pad, Азер Кочулу (Azer Koçulu) разрабатывал еще библиотеку под названием kik. Так же, существовала компания Kik, которая решила запилить себе свою собственную библиотеку, чтобы другим разработчикам было проще использовать их чатботы. Но - беда! Азер уже занял имя kik в публичном реестре пакетов npm. И вот, патентный менеджер Кик Боб Страттон пишет имейл Азеру, и просит его переименовать свой пакет. Тот не соглашается. Слово за слово, обложили друг друга хуями и на том разошлись.


Боб: Мы не хотим быть гондонами, однако Кик - зарегистрированая торговая марка, и, если ты хочешь использовать это имя то наши юристы...

Азер: Хаха, ты действительно ведешь себя как гондон. Так что иди нахуй и не пиши мне больше

Позже Боб предложил заплатить за имя, а мистер Кочулу попросил 30 000$ за "трудности отказа от моего проекта ради кучки корпоративных хуев".

Так ничего и не решив между собой, патентный менеджер Страттон побежал просить помощи у npm. Те хуй к носу прикинули и ответили, что да, устанавливая пакет kik пользователи скорее всего ожидают получить пакет для работы с чатботами kik а не что-то совершенно инное. И решили отобрать название от Азера и отдать его компании.


- Я знал вас много лет. А вы... - обиделся Азер. - Я не хочу больше быть частью NPM. Удалите все мои 273 пакета.


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

Чтобы вы понимали масштаб проблемы. Даже в 2020, устаревший пакет, который обновляли 2 года назад, в неделю загружают больше четырех миллионов раз.

Завалилось все не прямо так, чтобы рабочие сайты упали, конечно же. Просто внести изменение в них стало невозможным. Так как часть процеса - установка зависимостей, а она не работала, потому что left-pad не было в реестре.

Fun fact: проект чат компании Kik тоже пострадал.


Пока все держались за голову и плакали, один шустрый разработчик понял простую вещь. Раз left-pad больше нет в реестре, значит имя свободно. Он быстренько опубликовал пакет под тем же именем с той же функцией - как вы помните, она очень простая - и довольный уселся пить чай с печеньками, ожидая хвалы спасителю. Однако не все так радужно было в Королевстве Фронтенда. Многие библиотеки умудрились в зависимости прописать еще и строгую версию библиотеки. Им подавай только left-pad 0.0.3. Шоб вдруг чего не случилося.  Но и это порешалось. Договорившись, дядьки с npm позволили опубликовать новый код, который на 100% совпадал с старым, под той же версией 0.0.3. А шустрого разработчика, почему то, не упоминают в источниках и я его имени не нашел.

На этом заканчивается история. Мир Веб Паутины был спасен, Азер ушел из NPM а Кик получили свое имя в реестре. Если посмотреть туда сейчас, то можно увидеть, что "кучка корпоративных хуев" так и не удосужилась опубликовать свою библиотеку. То есть Азера обидели, npm прогнули и на этом удовлетворились.


На написания этого поста вдохновила история о core-js Ответ на пост «Современное програмирование».


Типо источник

7
DELETED
Автор поста оценил этот комментарий
Лицензия замечательная и в тему событий! Случайно не расшифровывается как "What The Fuck? Public License"?
Иллюстрация к комментарию
раскрыть ветку (1)
12
Автор поста оценил этот комментарий

Do What The Fuck You Want To Public License

http://www.wtfpl.net/about/

показать ответы
3
Автор поста оценил этот комментарий

Ух ты, сколько плюсов. А знаете, я, кроме программирования, еще и песни пишу.

Предпросмотр
YouTube4:38
22
Автор поста оценил этот комментарий

Была ещё библиотека is-promise, которая состояла всего из двух строк (!) кода js. И вот эту библиотеку использовали более чем в 2.5 миллионах (!!!) проектов. Новая версия оказалась несовместима со стандартами ES-модуля. Пострадали такие известные фреймворки и библиотеки как React, Angular, Nuxt и другие

https://habr.com/ru/company/itsumma/news/t/499218/

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Они, по ходу, потом просто зарелизили major версию с этими изменениями, потому что в npm уже 4.х а в статье пишут о 2.2.0.

0
Автор поста оценил этот комментарий

А с тайпскриптом - справляется и с каррингом и композицией.

т.е. тот же vscode корректно мне подскажет, что вот тут я поиспользовал карринг из хрен пойми какой библиотеки? или надо плагины подключать, чтобы при использовании lodash или ramba среда давала мне подсказки, что вот тут я сделал карринг и аргументы вот такие надо?


Кодстайл на фронтенде - никаких классов. Даже в реакте компоненты-функции.

ну это и понятно, с современными mvvm фреймворками с их компонентами ООП не нужен почти никогда. некоторые функциональные подходы (те же map/filter/reduce, иммутабельность, стремление к "чистоте") мы у себя практикуем испокон веков, но ничего более серьезного.. а что вы из более серьезного ФП используете в реакте на фронте, и чем оно реально помогает?


Лишние функции обертки это антипаттерн. Это много раз повторяется в книге, что я советовал.

книга занятная, начал читать, наткнулся на недопонимание или косяк автора, он пишет в главе 3, что

const decrementHP = p => p.set('hp', p.get('hp') - 1);

это чистая функция.. но тут же у нас мутация передаваемого в аргументе объекта, какая ж это чистая функция???

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Надо ставить @types/ramda. Два года назад там были проблеммы с тем, что нужно было отдельно импортировать тип для стабильного числа аргументов, но потом один энтузиаст это подфиксил. И да, оно подсказывает и даже падает при компиляции, если неверные аргументы передать.

В реакте на фронте - в основном что то маленькое, как пример с массивом с прошлого коммента, или когда пишу отдельную логику типа апи клиента. И я бы не сказал, что оно прям так помогает, что без него никак. Просто немного меньше кода, стройнее все. Тяжелее сделать ошибку. Делал недавно проект для а/b тестирования, в рамках того же энтерпрайза, там было где развернуться. Еще у нас куча кастомных скриптов что поддерживают монорепо.

1
Автор поста оценил этот комментарий

моветон? спорное заявление.

явное лучше неявного. задавая аргументы явно, вы даете статическому анализатору / компилятору информацию, как используется метод, среда разработки дает разработчикам подсказки, как использовать метод..

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

ооп в js боль только для тех, кто не умеет в ооп. сейчас в js и конструкторы, и наследование, скоро приватные поля приедут. нужны более сложные вещи - typescript.


Функциональный подход для меня выглядит красивее. Почти всегда короче и понятнее, если привыкнуть

самое важное тут - "для вас" и "если привыкнуть".. небольшие проекты и команды - ок.. но я говорю про энтерпрайз код, сейчас код разрабатываете вы, а через неделю будет дорабатывать вася-джуниор.. разбираться в хорошо структурированном явном коде легче, чем в композициях и каррингах, особенно когда еще и среда разработки не может подсказать (см. предыдущий абзац).


Чистые функции легче тестировать.

это бесспорно, и никто не запрещает писать чистые функции так, как я приводил примеры выше, только без магии карринга и композиций.


p.s.: вмеcто array.map скорее всего вы хотели array.forEach

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Лишние функции обертки это антипаттерн. Это много раз повторяется в книге, что я советовал.

Среда без тайпскрипта и так подсказывает всякую дичь. Что вебшторм, что вскод. А с тайпскриптом - справляется и с каррингом и композицией.

Я перед js кодил на c#. Перейдя в js 5 лет назад пробовал продолжить писать так же. Однако, даже на TS намного сложнее построить стройную архитектуру классов, нет таких элементов как abstract, virtual. И, не следует забывать, что внутри те же прототипы спрятаны, что и раньше.

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

Кстати, я работаю в энтерпрайзе, которому больше 10 лет. У нас сейчас около двух сотен разработчиков. Кодстайл на фронтенде - никаких классов. Даже в реакте компоненты-функции.

Нет, именно map. Предпочитаю создавать новый а не изменять существующий

показать ответы
0
Автор поста оценил этот комментарий

1. Вариант с логированием. Тут карринг не нужен как таковой. На чистом js выглядит даже проще:

const log = (f, c, level, data) => { ... };

const warn = (data) => log(fetch, config, 'warn', data);

А с использованием ООП так еще более опрятно и гибко:

class Logger {

  constructor(fetch, config) {  ...  }

  log(level, data) {  ...  }

  warn(data) {

    this.log('warn', data);

  }

}

2. Функция добавления конкретного класса - чистая фикция, как сказал бы Мартин Фаулер. Не плодите сущности, иначе словите себя на том, что у вас 100500 функций и 99% используется всего 1 раз.

3. Композиция функций для валидации телефона это пиздец какой-то. Понятно, что вы в своей команде вовсю используете трюки ФП и для вас это привычно. Но для меня (как обычного разработчика с 15 лет стажа)))) это выглядит непонятным и неочевидным. В простом императивном подходе куда очевидней:

const phoneValidator = (value) => { ... };
const eventHandler = (target, klass, validator) => {
  if (validator(target.value)) {
    validator.classList.remove(klass);
  } else {

    validator.classList.add(klass);

  }
}
phoneInput.addEventListener('keyup', (e) => eventHandler(e.target, 'GB', phoneValidator));

хотя, если честно, в обоих случаях говнище)))

Ну и другой момент, манипуляции dom'ом и свое связывание модели / представления в наше время выглядит уже странно: react, vue, angular наше все.

P.S.: по ФП почитаю, спасибо ))

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Так делать - моветон. Прелесть каррирования в том, что оно позволяет сохранить столько аргументов, сколько хочешь. Можно в одном месте сохранить первый, сделав с общей функции немного более специфичную, а потом добавить ещё 1-2 в другом месте. Часто пишу

arr.map(append ('xxx'))

Вместо

arr.map(el=>append(el, 'xxx'))

В функциональных языках функции каррированы по дефолту


Ооп в js это боль, по сравнению с нормальным языком типа c#.  Поэтому я использую функции и радуюсь жизни.


Ну и вообще, понятно, что это все можно сделать иначе. Функциональный подход для меня выглядит красивее. Почти всегда короче и понятнее, если привыкнуть. Чистые функции легче тестировать.

показать ответы
0
Автор поста оценил этот комментарий

в дополнение к своему комменту, я тут понял, что композиция функций в последнем примере для валидации поля ввода дает ложное ощущение "универсализма", потому что по факту:

1. для поле ввода input / textarea / select (не multiple)  текущим элементом (getTarget) всегда будет event.target, а значением поля (getValue) всегда будет target.value

2. для select multiple  getValue будет отличаться, да.. но спросите себя, используете ли вы этот атавизм 00-х?

3. для radio / checkbox весь этот код не будет работать, т.к. надо пробегаться по всему множеству значений.. да и к тому же нет смысла менять class на чекбоксах )))

в итоге реально рабочим получается вариант 1.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

В последнем случае лучше сделать через ramda.prop а не городить велосипед с первыми двумя функциями.

0
Автор поста оценил этот комментарий

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

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

```js

export const log = curry((fetch, config, logLevel, data) => {

// сложная функция для логирования в разные апи клиенты в зависимости от конфига

})


//в самом начале

const warn = log(theFetch, theConfig, 'warn');


//сколько угодно раз в коде

warn('something just happened');

```


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


```js

const addClass = (className, element) => {/*безопасное добавление класса*/}


const hideElement = addClass('hidden');

```

Или pipe, что композиция наоборот

```js

const validatePhoneNumber = pipe(

    getTarget,

    getValue,

    getValidationClass('GB'),

    setWrapperValidationState

);

phoneInput.addEventListener('keyup', validatePhoneNumber );

```


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


Советую эту книгу https://github.com/MostlyAdequate/mostly-adequate-guide-ru

показать ответы
0
Автор поста оценил этот комментарий

где в проекте вы это используете? вот прямо кусок кода скопируйте )))

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Вообще код под нда, но я посмотрю, что можно сделать)

показать ответы
0
Автор поста оценил этот комментарий

а средства языка разве сложнее?

function f(a, b) {}

c = (b) => f(a, b);

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

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Какая магия по капотом? Каррирование это базовая операция на функцией. Его, как и композицию, я использую почти всегда. Особенно, если фронт без реакта, то это вообще единственный вариант упростить работу с dom

Средствами языка на 3+ аргумента это уже уродливо

показать ответы
0
Автор поста оценил этот комментарий

Как всегда когда не-программисты пишут о программировании получается говно и легенды.

Никакая половина веб-приложений никуда не попадала. Все установленные приложения работали в штатном режиме. Заблокировалось только разворачивание НОВЫХ приложений что и решили за пару дней.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Любой ci/cd процесс использует npm install. Тоесть, ни один тестовый сервер не мог перебилдиться с новой версией кода. Плюс, если кто-то добавил библиотеку и запушил, то установить ее - тот еще квест. Разве что нодмодули архивом перекидывать друг другу. Вот прям глобального краха не произошло, однако работа встала конкретно. А за пару дней решили тем, что пакет восстановили.

показать ответы
0
Автор поста оценил этот комментарий

yarn add же ))

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

pnpm

Автор поста оценил этот комментарий

приведите пример из жизни, где вам понадобился lodash? лет 10 назад, когда в js не было поддержки filter/map/reduce либы типа underscore / lodash были полезными, но сейчас?

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

_.curry

показать ответы

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества