Pull to refresh
8
0
Приймачук Василий @ActiveObject

User

Send message
Вероятно из за того что язык сам по себе это еще не гарантия того, что новые приложения будут разрабатываться быстрее, будут надежнее и т.д. Есть еще экосистема, где много библиотек на все вкусы, есть устоявшиеся паттерны. Так что просто взять и выбрость годы наработок не получиться. А вот сделать нормальный интероп между языками — это задание не из легких.

Кроме того js не такой уж и страшный зверь как его все выставляют, жить можно, немножко подправить и все будет ок (ES6).
Всё, что рекомендуют при разработке на JS — это функции и функции, хотя php-ньюблам за это буквально руки отрывают

Есть обычные функции, типа как в php4 или С, и есть функции высшего порядка, как в js. Так вот не поверите, но с помощью последних можно писать очень лаконичный код. Собственно все функциональные языки программирования используют функции как основной способ абстракции.
Ну прям php4? Это ничего что у js из коробки и объекная модель и функции высшего порядка.
Никто не мешает, но я не вижу никакого смысла использовать Object.freeze для персистентных структур. Все реализации, которые я видел, используют непрозрачную trie-like структуру, и менять ее вручную — это уже извращение.
А объявления переменных, например arr лучше выносить вверх скоупа.


Вот этого я не понимаю. Зачем? Как будто вернулся в школьные времена, к родному Паскалю. Да, есть variable hoisting, но это проблема только в очень больших функциях с кучей мелких переменных.
Уже есть — mori, immutable-js. Не настолько удобно как в ClojureScript, но работать можно.
Тут дело даже не в производительности Object.freeze. Тут дело в подходе. С Object.freeze на каждое изменение придется копировать всю структуру, и это очень плохо. Никто так не делает. Ниже я писал про персистентные структуры данных, которые применятся при реализации иммутабельних структур, и которые дают очень даже хорошие результаты.
Видимо, зависит от того, как применять. Я далек от функционального программирования. Расскажите, а когда такая надобность возникает?

Вся прелесть использования иммутабельных структур данных заключается в отсутствии побочных эффектов. Это чертовски здорово помогает рассуждать о коде, как он работает, ведь можно исключить целый пласт проблем связанных с тем, что кто-то, где-то поменял структуру твоих данных. Иммутабельние структуры дают тебе гарантию, что:
1) данные, которые ты используеш, не будут меняться извне
2) ты можеш делать что угодно с данными, и ты не повлияешь на другой код

Поэтому, если ты уже взялся использовать иммутабельные данные, будь добр не меняй эти данные in-place, иначе вся суть их использования будет утрачена.

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

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

Я к тому, что иногда создание ссылки на прототип может быть «дешевле», чем копирование всех полей по честному.

Не обязательно копировать всю структуру целиком. Есть целое семейство структур данных, которые позволяють значительно повысить производительность при работе с иммутабельными данными, так называемые persistent data structure.

С тем же Object.freeze мы можем гарантировать что структура будем неизменяемой, но этого недостаточно. Производительность будем ужасная. Тут нужны персистентные структури данных. А это уже на коленке не сделаешь.
Полиморфизм можно реализовать не только через виртуальные методы на обьектах. Есть же мультиметоды, протоколи (clojure).
Можно взять PersistentVector из clojure. На первый взгляд структура похожая на hamt, то же префиксное дерево с нодами по 32 елемента.
А Вы не думали вынести Map и Vector в отдельные npm модули? На данный момент кроме mori нет ничего пригодного для продакшена. Я уже сам начал пилить свой велосипед, но пока что это все суровая альфа.
Вот, пожалуйста:

var futureResult = db.getData.bind(db, filter);
var anotherFutureResult = db.getAnotherData.bind(db, anotherFilter);

waitFor(futureResult, anotherFutureResult, function(error, someData, anotherData) {
  // ... do the job
});


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

function waitFor() {
  var args = Array.prototype.slice.call(arguments);
  var done = args[args.length - 1];
  var result = new Array(args.length - 1);
  var hasError = false;
  var left = args.length - 1;

  args.slice(-1).forEach(function(asyncFn, i) {
    asyncFn(function(error) {
      if (error) {
        hasError = true;
        return done(error);
      }

      result[i] = Array.prototype.slice.call(arguments, 1);
      left--;

      if (left === 0) {
        return done.apply(null, [null].concat(result));
      }
    });
  });
}


Тот же async — это по сути набор специальних комбинаторов для разных сценариев использования.
Следуя вашей логике, функции в js тоже не компонуются в чистом виде (в js нет оператора для композиции функций). Извиняють сударь, но это смешно.

Я веду к тому, что нодовский коллбеки как раз отлично компонуются. Есть конвенция: коллбек — последний аргумент для асинхронной фунции, ошибка — первый аргумент коллбека. Написать функцию композиции при условии соблюдения конвенции легко, причем можно вариировать семантику обработки ошибок, порядок вычислений.

То что действительно неудобно, так это CPS.
Господа, но колбэки не компонуются! Это гребаный приговор.


Второй раз за неделю вижу подобное утверждения. Кто-то может объяснить почему же они не компонуются?
Написать async compose для ноди не так сложно.
Прототип обьекта можно получить используя Object.getPrototypeOf.
Эта картинка только доказывает невежество тех, кто никогда не читал эти книги. Бо́льшая часть The Definitive Guide — это описание работы в браузерном окружении, о котором в The Good Parts ни слова.
Строго говоря, объекти в js не имеют свойства prototype. Есть внутренне свойство [[Prototype]], недоступное в клиентском коде. Так как иногда все же надо иметь доступ к прототипу объекта, для удобства ввели свойство __proto__, которое как раз указывает на объект-прототип. Более того, в es5 есть стандартный метод Object.getPrototypeOf(obj) для этих целей. Собственно a.__proto__ === Object.getPrototypeOf(a).
Сложно представить язык, где функции — обьекты первого класса, и нет поддержки замыканий. Как правило, если есть поддержка первых, вторые идут «из коробки».
Все правильно в статье. Если значение не примитив, будет вызван метод valueOf. Если значение, которое вернет valueOf, не примитив, тогда будет вызван метод toString для исходного обьекта. Так как массив не имеет собственного метода valueOf, он наследует Object.prototype.valueOf, который по умолчанию возвращает ссылку на исходный обьект.

var arr = [];
arr.valueOf() === arr; // true


9.1 ToPrimitive
8.12.8 [[DefaultValue]] (hint)

Information

Rating
Does not participate
Location
Луцк, Волынская обл., Украина
Registered
Activity