В поисках Грааля каждые 16 минут на Земле ...
От: c-smile Канада http://terrainformatica.com
Дата: 09.03.15 01:28
Оценка: +3 :))) :)))
... рождается котёнок JavaScript framework.

Исследования показали что Todo List это самое сложное веб приложение что вы можете написать перед тем как новый, еще лучший framework будет изобретен...

TodoMVC сайт на настоящий момент сожержит 63 (!) имплементаций Todo List webapp с использованием разных frameworks (помимо vanilla JS и jQuery).

...

И вот казалось Грааль найден


но! Angular команда решила что Angular2 не будет совместим с Angular1.

Йиии-хх-аа, эта пестня хороша — начинай сначала

Весь текст тут http://www.allenpike.com/2015/javascript-framework-fatigue/
Re: В поисках Грааля каждые 16 минут на Земле ...
От: vsb Казахстан  
Дата: 09.03.15 02:45
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Йиии-хх-аа, эта пестня хороша — начинай сначала


Сейчас react.js модно.

А MVC хорошего как не было, так и нет нигде
Отредактировано 09.03.2015 2:46 vsb . Предыдущая версия .
Re[2]: В поисках Грааля каждые 16 минут на Земле ...
От: c-smile Канада http://terrainformatica.com
Дата: 09.03.15 03:48
Оценка: 20 (3)
Здравствуйте, vsb, Вы писали:

vsb>А MVC хорошего как не было, так и нет нигде


А что такое хороший MVC?

Если "хороший" это "тот который есть не просит" то вот 60 lines of code от меня https://github.com/c-smile/spapp
Re: В поисках Грааля каждые 16 минут на Земле ...
От: Mamut Швеция http://dmitriid.com
Дата: 09.03.15 08:33
Оценка:
CS>но! Angular команда решила что Angular2 не будет совместим с Angular1.

Про это на твиттере кто-то правильно сказал: Angular продвигается Гуглом, и Гугл использует его в 0 своих проектах. React.js продвигается Facebook'ом, и используется в его реальных проектах.


dmitriid.comGitHubLinkedIn
Re[2]: В поисках Грааля каждые 16 минут на Земле ...
От: maxkar  
Дата: 09.03.15 09:35
Оценка: 2 (1)
Здравствуйте, vsb, Вы писали:

vsb>А MVC хорошего как не было, так и нет нигде


А самому сделать? Я свой идеальный API уже знаю, умею писать и потихоньку алгоритмическую базу обновляю. Называется реактивное программирование и выглядит так:
var x = Behavior.variable(3);
var y = Behavior.variable(5);

function calc(x, y, z) {
  return x + y * z;
}

var res = Behavior.apply(calc, [x, y, 7]);
var elt = UI.div(UI.text(res));
Behavior.appply(alert, res);

x.set(10);
y.set(20);


При вызове set все нужные функции перевычисляются. (т.е. в примере будет два alert'а). В отличие от того же ангуляра, прекрасно работает с массивами и позовляет писать что-то вроде

function filter(spec, items) {
  var res = [];
  items.foreach(function(item) {
    if (item.firstName == spec.firstName && item.lastName == spec.lastName)
      res.append(item);
  });
  return res;
}

function mkSpec(firstName, lastName) {
  return { firstName : firstName, lastName : lastName };
}

var firstName = ...
var lastName = ...
var allItems = ...

var itemsToShow = Behavior.apply(filter, [Behavior.apply(mkSpec, [firstName, lastName]), allItems]);
var itemPages = Behavior.apply(paginate, [itemsToShow]);
var pageToDisplay = Behavior.apply(Arrays.itemAt, [itemPages, currentPage]);


Нет никаких "циклов перевычислений" (с ангуляром — беда на массивах). В отличие от того же react.js, оно гвоздями не прибито к DOM (у меня вообще подозрение, что react.js тоже все перевычисляет, иначе virtual DOM просто не нужен). API чистый и удобный. Во многих местах можно писать чистые функции и потом биндить их к модели (а чистые функции хорошо тестировать).

Всякие мелочи удобно реализуются. Тот же человекообразный Async на Behavior (вместо страшных promise в CPS будет Async.apply(fn, args...)). Желающие могут посмотреть реализацию async у меня.

Я на эту тему могу говорить еще долго, но будет ли кто-то слушать? Именно на js на библиотеку посмотреть нельзя. Нету ее пока, у меня нет задач, где она нужна (плюс я не уверен, что single-page app так часто нужны, для чего-нибудь простого API от c-smile выглядит хорошо). Но пишется меньше, чем за неделю. Версию на scala можно найти в репозитории по ссылке выше (планируются существенные улучшения в математике без изменения API), там же полностью рабочий десктопный пример. Могу и под достойную задачу на js написать версию. Или можем обсудить и я могу присоединиться к вашей команде и показать, как и что. У меня задачи достойные для reactive programming слишком быстро кончаются, нужны адоптеры
Re[2]: В поисках Грааля каждые 16 минут на Земле ...
От: Sharov Россия  
Дата: 09.03.15 09:59
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Про это на твиттере кто-то правильно сказал: Angular продвигается Гуглом, и Гугл использует его в 0 своих проектах.


В гмейле вроде бы используется. Разработчики Angular из этой группы.
Кодом людям нужно помогать!
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: maxkar  
Дата: 09.03.15 11:02
Оценка:
Здравствуйте, Sharov, Вы писали:

S>В гмейле вроде бы используется. Разработчики Angular из этой группы.


Не получилось найти ангулара. Ни в network browser, ни в разметке. Коллективный разум говорит, что они используют Closure Tools.
Re: В поисках Грааля каждые 16 минут на Земле ...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.03.15 14:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>но! Angular команда решила что Angular2 не будет совместим с Angular1.

Он и между минорными релизами был не очень-то совместим.
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: vsb Казахстан  
Дата: 09.03.15 14:57
Оценка: +1
Здравствуйте, c-smile, Вы писали:

vsb>>А MVC хорошего как не было, так и нет нигде


CS>А что такое хороший MVC?


Это где есть model, view, controller и стрелочки стоят в нужном направлении, как в smalltalk-е было. Всё остальное это не MVC (не обязательно хуже, но называться MVC не должно).
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: vsb Казахстан  
Дата: 09.03.15 14:58
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Здравствуйте, vsb, Вы писали:


vsb>>А MVC хорошего как не было, так и нет нигде


M>А самому сделать?


Периодически хочу, но лень побеждает. Да и не пишу пока больших JS проектов, где это реально надо, лапшекода хватает.
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: c-smile Канада http://terrainformatica.com
Дата: 09.03.15 18:58
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Я свой идеальный API уже знаю, умею писать и потихоньку алгоритмическую базу обновляю. Называется реактивное программирование и выглядит так:


Как-то это похоже на knockout.js , нет ?
Re[2]: В поисках Грааля каждые 16 минут на Земле ...
От: c-smile Канада http://terrainformatica.com
Дата: 09.03.15 19:49
Оценка: +3 :)
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, c-smile, Вы писали:


CS>>но! Angular команда решила что Angular2 не будет совместим с Angular1.

G>Он и между минорными релизами был не очень-то совместим.

У меня такое впечатление что основная толпа "руби-роидов" перебежала с RoR на Angular.
Во всяком случае такие же шумные и энтузиастнутые ...

А вообще количество TodoMVC конечно зашкаливает.

Проще написать именно то что надо здесь и сейчас на jQuery чем найти 1 зерно в 63 плевелах.
И вот когда ты это своё написал, по науке, с абстракциями и всеми делами то тут же рогатый тебе и шепчет "Смотри как классно! Давай выкладывай это дело на TodoMVC — осчастливь человечество".
Re[4]: В поисках Грааля каждые 16 минут на Земле ...
От: Sharov Россия  
Дата: 09.03.15 19:55
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Здравствуйте, Sharov, Вы писали:


S>>В гмейле вроде бы используется. Разработчики Angular из этой группы.


M>Не получилось найти ангулара. Ни в network browser, ни в разметке. Коллективный разум говорит, что они используют Closure Tools.


Да, это я похоже ошибся -- wishful thinking. Но можно погуглить "where does google use angularjs", и среди прочих будут действительно
разработки гугла на Angular. Наример, YouTube on PS3.
Кодом людям нужно помогать!
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: Sharov Россия  
Дата: 10.03.15 10:28
Оценка:
Здравствуйте, Sharov, Вы писали:

Вот еще можно посмотреть крупные продукты, в которых используется Angular.
Кодом людям нужно помогать!
Re[4]: В поисках Грааля каждые 16 минут на Земле ...
От: maxkar  
Дата: 15.03.15 11:30
Оценка: 22 (4)
Здравствуйте, c-smile, Вы писали:

M>>Я свой идеальный API уже знаю, умею писать и потихоньку алгоритмическую базу обновляю. Называется реактивное программирование и выглядит так:

CS>Как-то это похоже на knockout.js , нет ?

Да, похоже. Многие API будут похожи друг на друга. В конце концов, behaviour/observable — это монада. Там всего лишь три элемента: тип, return и bind. Для реактивного программирования добавляется variable. Поэтому если принято решение делать архитектуру на "маленьких observable (т.е. как в knockout том же, каждое свойство observable вместо их контейнера), она будет в чем-то похожа на knockout.

А вот в деталях (очень важных деталях) мой API отличается от knockout. Это скорее flapjax. В свое время я за основу как раз брал flapjax, но его не было под нужную платформу. Поэтому API (и структура UI) сделана по его мотивам, а реализация уже своя.

Теперь покажу те самые важные детали:
function blackMagic(x, y, z) {
  return x + y *z;
}

//Knockout:
var x = ko.observable(5);
var y = ko.observable(7);
var z1 = ko.computed(function() {
  return blackMagic(x.value(), 42, y.value());
});
var z2 = ko.computed(function() {
  return blackMagic(4, x.value(), x.value());
});

//Mine:
var x = R.variable(5);
var y = R.variable(7);
var z1 = R.apply(blackMagic, [x, 42, y]);
var z2 = R.apply(blackMagic, [4, x, x]);


У меня меньше boilerplate, что уже само по себе хорошо. Но важнее то, что "мой" API заставляет разработчиков писать чистые функции а не "привязанный к модели computed". Эти функции можно использовать в разных контекстах, проще тестировать.

Вторая мелочь — трекинг зависимостей и количество обновлений:
function f1(x, y) {
  return 2 * x + y;
}
function f2(x, y) {
  return x - y + 4;
}
var a = R.variable(1);
var b = R.apply(f1, [a, 3]);
var c = R.apply(f2, [a, 9]);
var res = R.apply(f1, [b, c]);
R.apply(alert, [res]); 
// Сколько будет алертов при вычислении следующей строки:
a.set(10);

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

Третья мелочь. Управление временем жизни моделей. Обычно оно делается через weak references. Я уже и не помню, почему я не стал делать так. Либо меня смущало, что на вершинах там живет DOM (и могут быть какие-то расходы по быстродействию до запуска GC). Либо просто было изобретено не мной. Поэтому управление временем жизни приняло такую форму:
// Какие-то глобальные (или долгоживущие) observable.
var globalA, globalB;

// Временный scope (например, диалоговое окно)
var session = R.session();
var x = R.variable(123);
var a = session.proxy(globalA);
var b = session.proxy(globalB);
var y = R.apply(fn, [a, b, x]);
//...
// При закрытии окна
session.destroy();

У меня при необходимости вся временная модель "отрезается" от родительской за один вызов и по линии отреза.

Итого. Да, с одной стороны, похоже. Но с другой стороны, есть и отличия, которые хорошо проявляются только на больших проектах. На hello, world разницы особой нет.

P.S. Есть и аналог knockout.js в мире скала. Это scala.rx. Там как раз "интрузивные" применения функций и сложные вычисления.
Re[2]: В поисках Грааля каждые 16 минут на Земле ...
От: dalmal  
Дата: 15.03.15 13:34
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Про это на твиттере кто-то правильно сказал: Angular продвигается Гуглом, и Гугл использует его в 0 своих проектах.

Вроде ж используется, просто во внутренних проектах, не? Всякая там автоматизация тыры-пыры.

M>React.js продвигается Facebook'ом, и используется в его реальных проектах.

Это разные фреймворки для разных вещей.
Re[3]: В поисках Грааля каждые 16 минут на Земле ...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.03.15 20:31
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Всякие мелочи удобно реализуются. Тот же человекообразный Async на Behavior (вместо страшных promise в CPS будет Async.apply(fn, args...)). Желающие могут посмотреть реализацию async у меня.


Покажи простецкий кейс — выполнить долгий аджакс запрос + несколько подготовительных в начале + несколько заключительных в конце. Все выполняется последовательно. Вся эта цепочка должна поддерживать отмену, прогресс и очень хочется легкой, прозрачной отладки.

M>Я на эту тему могу говорить еще долго, но будет ли кто-то слушать? Именно на js на библиотеку посмотреть нельзя.

...
> Но пишется меньше, чем за неделю.

Это сказки. Чтото реактивное можно и за неделю. А чтото концептуальное, годное для продакшна в JS, пишется долго и мучительно. За примерами см например bacon.js и подобные либы.
Re[4]: В поисках Грааля каждые 16 минут на Земле ...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.03.15 20:33
Оценка:
Здравствуйте, vsb, Вы писали:

M>>А самому сделать?


vsb>Периодически хочу, но лень побеждает. Да и не пишу пока больших JS проектов, где это реально надо, лапшекода хватает.


Вся реактивщина работает на порядок медленнее тех же промисов. И если промисы можно выпрямить в линейный код с помощью yield, лифтинга и тд, то реактивщину вспотеешь спрямлять.
Re[5]: В поисках Грааля каждые 16 минут на Земле ...
От: c-smile Канада http://terrainformatica.com
Дата: 15.03.15 20:39
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Здравствуйте, c-smile, Вы писали:


M>//Mine:

M>var x = R.variable(5);
M>var y = R.variable(7);
M>var z1 = R.apply(blackMagic, [x, 42, y]);
M>var z2 = R.apply(blackMagic, [4, x, x]);
M>[/code]

Я для Sciter написал был что-то такое reactive/data-bound по имени +plus ( {sciter-sdk}/samples/+plus )

script:

namespace KindOfModel {
  var x = 5;
  var y = 7;
  var z1,z2;
  
  @observing "x" "y"  
    function() { z1 = x + y + 42; }

  @observing "x" 
    function() { z2 = 2 * x + 42; }
}


делает то же самое что и у тебя как я понимаю. Только кроме того еще binding с UI:

<form model="KindOfModel">
  <label>X</label> <input(x)>
  <label>Y</label> <input(y)>
  Z1: <output(z1)> and Z2 <output(z2)>
</form>


Без binding c UI я так понимаю это всё смысла не имеет.
Хотя если мне не изменяет память вроде как Prolog позволял деклартивно вычислительные сети рисовать. Но могу ошибаться, давно это было.
Re[4]: В поисках Грааля каждые 16 минут на Земле ...
От: maxkar  
Дата: 18.03.15 22:49
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, maxkar, Вы писали:


M>>Всякие мелочи удобно реализуются. Тот же человекообразный Async на Behavior (вместо страшных promise в CPS будет Async.apply(fn, args...)). Желающие могут посмотреть реализацию async у меня.


I>Покажи простецкий кейс — выполнить долгий аджакс запрос + несколько подготовительных в начале + несколько заключительных в конце. Все выполняется последовательно.

var group = Async.group();
var preop1 = group.add(startPreop1());
var preop2 = group.applyAsync(startPreop2, [preop1]);
var preop3 = group.applyAsync(startPreop3, [preop2]);
var ajaxQuery = group.applyAsync(doLongLastingOp, [preop3]);
var postOp1 = group.applyAsync(startPostOp1, [ajaxQuery]);
var postOp2 = group.applyAsync(startPostOp2, [postOp1]);
var postOp3 = group.applyAsync(startPostOp3, [postOp2]);

R.apply(function(state) {
  switch (state.state) {
    case 'progress' :
      console.log('Progress is ' + state.progress);
  }
}, [group.progress]);

// cancellation:
group.cancel();

// functions:
function startPreop2() {
  // Staightfroward. between ajax and async API.
  return Net.call(....);
}


В качестве бонуса могу предложить примерную реализацию group:

  Скрытый текст
Async.group = function() {
  // Observable array.
  var ops = R.Arrays.variable();
  // Observable array of observables!
  var progresses = R.Arrays.mapValues(ops, function(op) {
    // Это будет behavior!
    return op.progress;
  });
  // Observable array of "progress values"
  var flatProgresses = R.Arrays.flatten(progresses);
  // Create behaviour which is sum of all progresses in the 
  // observable array (reduce operation).
  var totalProgress = R.Arrays.reduce(flatProgresses, 0, function(sum, state) {
    switch(state.state) {
      case 'progress': return sum + state.progress;
      case 'success' : return sum + 1;
      case 'error' : return sum;
      default: return sum; // log error
    }
  });
  var totalElems = R.Arrays.lenghtBehaviour(flatProgresses);
  // Среднее арифметическое, допустим, мы так считаем прогресс.
  var progress = R.apply(function(prog, count) {
    return count > 0 ? prog / count : 0;
  }, [totalProgress, totalElems]);
  
  return {
    'add' : function(op) {
      ops.push(op);
    },
    'applyAsync' : function() {
      var op = Async.applyAsync(arguments[0], arguments.slice(1));
      ops.push(op);
      return op;
    },
    'progress' : progress,
    'cancel' : function() {
      ops.foreach(function(op) { op.cancel(); });
    }
  }
}


I>Вся эта цепочка должна поддерживать отмену, прогресс и очень хочется легкой, прозрачной отладки.


С отладкой все просто. Можно на нужные функции ставить брекпоинты и внутри них все отлаживать. Обработку ошибок вся цепочка берет на себя (если что-то упадет, все остальное тоже упадет).

А вот с отменой и прогрессом все не так просто как кажется. Здесь проблема именно в постановке задачи. Один из примеров (с group) я привел. Но дело в том, что это не всегда удобно. Например, у меня была задача в следующем виде. Грузим А. По данным из А параллельно грузим Б и В. Получив и Б, и В по данным из них грузим Д. А еще получив данные из Б мы грузим Г (Г от В не зависит). Что такое "прогресс" у Д? Это чисто ее прогресс или прогресс с учетом прогресса из В, Б и А? И если второе, то сколько там А считать? Та же история с отменой. Если я отменяю Г, должен ли я отменить еще и Б с А? Или не должен (так как от них зависит Д)? Ответы могут очень сильно повлиять на API и на реализацию.

По времени. group я набросал за 15 минут. Для production (с отладкой) я подобный API соберу и отлажу за час примерно. Причем group будет написан один раз и будет использоваться в нескольких десятках мест в приложении (см. пример выше). При этом на выяснение _удобного_ для задачи API я потрачу как минимум еще один час. А то и больше. Но зато API получится удобным для практических задач. А не так, как необходимость распаковывать параметры из массива в Promise.awaitAll(...).then(...) (может, там все-таки есть что-то более удобное ). И потом все время разработки я буду наслаждаться удобным API а не делать какие-то магические приседания вокруг библиотеки с целью заставить ее работать.

>> Но пишется меньше, чем за неделю.

I>Это сказки. Чтото реактивное можно и за неделю. А чтото концептуальное, годное для продакшна в JS, пишется долго и мучительно. За примерами см например bacon.js и подобные либы.

В каком смысле концептуальное? Что-то в духе неомодернистского абстракционизма? Так оно же неудобное! Там обычно что-то не реализовано для моих конкретных задач, сделано не так или делается через кучу лишних действий. В результате "концептуальное" решение получается одинаково неудобным для 90% всех реальных практических задач.

А вот по поводу "годное для продакшна" — это не сказки. Это реальность. Я делал это своими руками и выпускал на базе реактивного программирования реальные проекты (и большие, и учебные). Как ни странно, в реальных приложениях не так много различных UI-компонентов. Основная база (кнопочки, элементы ввода, текст) пишется не более, чем за неделю. Затем по мере продвижения проекта добавляются другие элементы (вроде tabbed pane), суммарно еще может на неделю по времени. На выходе — набор ровно тех UI-контролов, которые нужны данному конкретному проекту. И 90% задач становятся рутинными и простыми. У меня не возникает кучи мест, куда нужно что-то стороннее допиливать или с библиотеками бороться.

По рискам/срокам/инвестициям (под новый проект, "старое — не брать") оно пойдет примерно так:

Итого. К концу первого двухнедельного спринат я получаю все ядро (мини-фреймворк), ядро UI, удобное для проекта API (не приходится натягивать ужа на ежа через день) и первый функциональный экран. Если не торопиться, заниматься сторонними требованиями, обсуждениями и т.п. в одиночку к концу месяца все на месте и все работает. Если не с нуля, то много берется с предыдущих проектов, пишется только networking layer и вперед — делать функциональность. Никаких изучений кучи трактатов о том, как заставить какую-то библиотеку работать в моих конкретных задачах. Все очень сильно упрощается, так как задачи для компонентов очень хорошо известны. Новые программисты вводятся по схеме: "2 часа на объяснение реактивного программирование, 2 часа — показать, где лежат наши UI-компоненты, еще час-два — на асинк. На второй день — в бой, писать функциональность".
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.