Да, все в курсе, что автокатастроф и их жертв гораздо больше, чем авиа. Однако соотношение выживших (или непострадавших) в дтп к количеству дтп и выживших в авиакатастрофе к количеству этих самых катастроф должно разительно отличаться.
Я к тому, что в летном деле вообще права на ошибку нет, ни на одну, иначе RIP. Вот этот факт и давит на людей подсознательно имхо.
Звучит как-то похоже на «статику генерить и отдавать пыхой» :)
Ну т.е. в каком-то жестком хайлоаде это может и имеет смысл, иначе — еще один промежуточный уровень чего-то, что может поломаться. Мерфи почти всегда, сука, прав.
Скомпонуйте результаты выполнения этих двух асинхронных запросов без лишней писанины.
В Scala я сделаю так:
val futureResult = db.getData(filter)
val anotherFutureResult = db.getAnotherData(anotherFilter)
//Future[MyDataObj]
val completeResult = for(result <- futureResult; anotherResult <- anotherFutureResult) yield MyDataObj(result, anotherResult)
И это будет вполне scalish way, поскольку for скомпилится во flatMap, а это привет монадам, интерфейс которых имплементируется в scala.concurrent.Future. Все смотрится и работает целостно, без всяких конвенций и договоренностей.
Хм.
Понравились неявные преобразования объектов в json и обратно с ходу, ну и неблокирующие запросы офк.
Не особо радует документация на запросах сложнее find(), часто приходится лезть в API и гугл.
Вот так выглядит простенькая агрегация с подсчетом и группировкой:
val command =
BSONDocument(
"aggregate" -> "rooms",
"$pipeline" -> BSONArray(
BSONDocument("$match"->BSONDocument("owner._id"->userId)),
BSONDocument("$group"->BSONDocument("_id"->"$language", "count"-> BSONDocument("$sum"->1)))
)
)
val comm = Aggregate("rooms", Seq(
Match(BSONDocument("owner._id"->userId)),
GroupField("language")("count"->SumValue(1))
))
Db.db.command(comm)
Я пока этот запрос родил — прошерстил с десяток страниц апилок и гугл тредов.
Конечно, можно взять http(s) сервис, натянуть шаблонизатор и любимую либу к бд, собрать свой лего. Но опять же — деплой с нуля руками пиши, sbt ковыряй. Выполнимо, не суперсложно, но зачем?
Кстати, плей переезжает/переехал на spray, если мне не изменяет память.
Так да, я говорил о том, что не переписал прототип.
Однако есть мнение, что двигать по рельсам дороги стройной и милой архитектуры гораздо приятнее в том случае, если тебе не чинятся постоянные препятствия, которые вроде как обходишь, но вроде как еще одной библиотекой из сотни уже используемых, и вроде как и мило получается, однако неприятный осадок остается.
В сухом остатке меньше кода — меньше багов (не всегда, но чаще всего).
Написал бы я сейчас на JavaScript лучше, чем тогда? Несомненно. Это, возможно, даже выглядело и работало бы попроще. Опыт в решении задач одного типа — это опыт, его не пропьешь.
Однако есть еще одно но, я его в статье не упомянул, так как ну ооочень субъективно. Я получаю удовольствие от Scala, с ее статической типизацией внутри спокойнее как-то что ли. От JS я страдаю, поэтому даже нынешний фронтэнд писал на coffee + angular
Для колбэков мне придется писать обертку, которая либо будет считать количество окончившихся функций, либо станет полноценным Deferred/Promise. Да, да, я знаю про существование подобных библиотек для JavaScript. Но это же просто раздутые обертки к тем самым колбэкам.
Я к тому, что нормальных нативных решений на тот момент не было. Не знаю, как там сейчас промисы в ECMA поживают.
А все подобные либы и решения — обвязки, костыли, пусть иногда и красивые, но все же в парадигму языка вливаются не на 100%.
Да я с Iteratee итак навеселился вдоволь. Ребята вдруг решили, что кто-то по wsу будет гонять тонны мегабайт, поэтому СРОЧНО нужно делать асинхронные итераторы/энумераторы с возможностью вытягивать ограниченное количество данных. Благо, от стандартных on/push не отказались до конца.
Вот теперь хочу перенести WS соединения на акторы в новой версии фреймворка.
Если честно, приелось писать одно и то же ради писанины :) Хочу уже запустить корабль в плавание.
Возможно. Однако у меня не было на тот момент времени писать еще и обвязку типа реги/логина, логики доступа к комнатам и их рендера на js'e. Так что я просто взял ранее написанные пыхорешения, встали как влитые.
Сейчас-то все, само собой, на одной платформе работает.
Не год, а пять лет.
Не к коллекциям, а к компилятору, который настолько излишне усложнен, что нужно быть Эйнштейном от программирования, чтобы что-то там править. Хотя у него и были претензии к коллекциям, а именно что мутабельные и иммутабельные классы наследуются от одних родителей, все же основной посыл состоял в том, что все написано в угоду временной производительности и совместимости, нежели понятности и изменяемости, а виноват во всем компилятор.
Так и неоткуда им взяться. Если смутило слово «формошлеп», то я таким образом обозначил просто основную массу кодеров, которые просто используют готовые стеки инструментов, не заморачиваясь с low level деталями.
Я сам успешно написал и пишу сервисы на Scala + Play + Akka
Я не касался функционального программирования на Scala, для этого нужно сравнивать Scala с другими функциональными языками, он я не FP'шник (FP guy)
Есть всё же несколько вещей, которые мне не понравились, за чуть более чем шести летний опыт работы со Scala.
Oh wow.
Да и вообще, это уже сколько обсасывалось — пока клепаем милые case class'ы и просто пишем col.map { _.toString } — сложного ничего.
Как лезем в дебри самого .map с его implicit CanBuildFrom — начинается хардкор.
Вывод: Для конечного формошлепа скалка проста. Для либописателя уже все не так радужно и питонисто.
btw, чтоб не было ВНЕЗАПНЫХ имплиситов, на которые жалуется автор оригинала, нужно или нормальные либы юзать, где нормальные ребята все пишут через implicit classы внутри объектов, либо не импортить весь com.shiiiet.DAT_IMPLICIT_GOD_OBJECT._
Да, все в курсе, что автокатастроф и их жертв гораздо больше, чем авиа. Однако соотношение выживших (или непострадавших) в дтп к количеству дтп и выживших в авиакатастрофе к количеству этих самых катастроф должно разительно отличаться.
Я к тому, что в летном деле вообще права на ошибку нет, ни на одну, иначе RIP. Вот этот факт и давит на людей подсознательно имхо.
Ну т.е. в каком-то жестком хайлоаде это может и имеет смысл, иначе — еще один промежуточный уровень чего-то, что может поломаться. Мерфи почти всегда, сука, прав.
Просто чтоб это расчехлилось из rm — нужно много стараться.
Найти нужные классы, заполнить необходимые аргументы и т.п.
У них же .command сделан как раз для таких вот сложных запросов. Подход простой — нам впадлу описывать это в std api, поэтому сделаем вот так.
Скомпонуйте результаты выполнения этих двух асинхронных запросов без лишней писанины.
В Scala я сделаю так:
И это будет вполне scalish way, поскольку for скомпилится во flatMap, а это привет монадам, интерфейс которых имплементируется в scala.concurrent.Future. Все смотрится и работает целостно, без всяких конвенций и договоренностей.
Понравились неявные преобразования объектов в json и обратно с ходу, ну и неблокирующие запросы офк.
Не особо радует документация на запросах сложнее find(), часто приходится лезть в API и гугл.
Вот так выглядит простенькая агрегация с подсчетом и группировкой:
Я пока этот запрос родил — прошерстил с десяток страниц апилок и гугл тредов.
Отозвался в гугле на безысходность, вот еще цитату вспомнил.
Конечно, можно взять http(s) сервис, натянуть шаблонизатор и любимую либу к бд, собрать свой лего. Но опять же — деплой с нуля руками пиши, sbt ковыряй. Выполнимо, не суперсложно, но зачем?
Кстати, плей переезжает/переехал на spray, если мне не изменяет память.
Однако есть мнение, что двигать по рельсам дороги стройной и милой архитектуры гораздо приятнее в том случае, если тебе не чинятся постоянные препятствия, которые вроде как обходишь, но вроде как еще одной библиотекой из сотни уже используемых, и вроде как и мило получается, однако неприятный осадок остается.
В сухом остатке меньше кода — меньше багов (не всегда, но чаще всего).
Однако есть еще одно но, я его в статье не упомянул, так как ну ооочень субъективно. Я получаю удовольствие от Scala, с ее статической типизацией внутри спокойнее как-то что ли. От JS я страдаю, поэтому даже нынешний фронтэнд писал на coffee + angular
Но на добром слове спасибо.
Я к тому, что нормальных нативных решений на тот момент не было. Не знаю, как там сейчас промисы в ECMA поживают.
А все подобные либы и решения — обвязки, костыли, пусть иногда и красивые, но все же в парадигму языка вливаются не на 100%.
Вот теперь хочу перенести WS соединения на акторы в новой версии фреймворка.
Если честно, приелось писать одно и то же ради писанины :) Хочу уже запустить корабль в плавание.
Сейчас-то все, само собой, на одной платформе работает.
Не к коллекциям, а к компилятору, который настолько излишне усложнен, что нужно быть Эйнштейном от программирования, чтобы что-то там править. Хотя у него и были претензии к коллекциям, а именно что мутабельные и иммутабельные классы наследуются от одних родителей, все же основной посыл состоял в том, что все написано в угоду временной производительности и совместимости, нежели понятности и изменяемости, а виноват во всем компилятор.
Я сам успешно написал и пишу сервисы на Scala + Play + Akka
Oh wow.
Да и вообще, это уже сколько обсасывалось — пока клепаем милые case class'ы и просто пишем col.map { _.toString } — сложного ничего.
Как лезем в дебри самого .map с его implicit CanBuildFrom — начинается хардкор.
Вывод: Для конечного формошлепа скалка проста. Для либописателя уже все не так радужно и питонисто.
btw, чтоб не было ВНЕЗАПНЫХ имплиситов, на которые жалуется автор оригинала, нужно или нормальные либы юзать, где нормальные ребята все пишут через implicit classы внутри объектов, либо не импортить весь com.shiiiet.DAT_IMPLICIT_GOD_OBJECT._