Как стать автором
Обновить
18
Карма
0
Рейтинг
Антон Асташов @Astashov_Anton

Пользователь

Нужен ли мне Dart?

Пусть у нас есть куча вложенных футур:

import 'package:stack_trace/stack_trace.dart';
import 'dart:async';

Future<Null> blah() async {
  throw 'foo';
}

void main() async {
  var result = await new Future(() async {
    await new Future(() async {
      await blah();
    });
  });
}


Если мы это запустим, то получим что-то типа такого:

Unhandled exception:
Uncaught Error: foo
Stack Trace:
#0      blah.<blah_async_body> (file:///Users/anton/projects/mixbook/photo_prints_web/blah.dart:7:3)
#1      Future.Future.microtask.<anonymous closure> (dart:async/future.dart:144)
#2      _microtaskLoop (dart:async/schedule_microtask.dart:43)
#3      _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#4      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
#5      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
#6      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

#0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:895)
#1      _microtaskLoop (dart:async/schedule_microtask.dart:43)
#2      _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#3      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
#4      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
#5      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)


Нифига не понятно, откуда мы пришли в blah() когда случилось исключение. Но если мы это обернем в Chain.capture:

Future<Null> blah() async {
  throw 'foo';
}

void main() {
  Chain.capture(() async {
    var result = await new Future(() async {
      await new Future(() async {
        await blah();
      });
    });
  }, onError: (error, chain) {
    print(chain.terse);
  });
}


мы получим вот такое:

blah.dart 7:3        blah.<async>
===== asynchronous gap ===========================
dart:async           _Completer.completeError
blah.dart 10:1       blah.<async>
===== asynchronous gap ===========================
dart:async           Future.Future.microtask
blah.dart            blah
blah.dart 14:15      main.<fn>.<async>.<fn>.<async>.<fn>.<async>
===== asynchronous gap ===========================
dart:async           Future.Future
blah.dart 13:17      main.<fn>.<async>.<fn>.<async>
===== asynchronous gap ===========================
dart:async           Future.Future
blah.dart 12:28      main.<fn>.<async>
===== asynchronous gap ===========================
dart:async           Future.Future.microtask
blah.dart            main.<fn>
package:stack_trace  Chain.capture
blah.dart 11:9       main


Такой себе нормальный стектрейс, хоть и от вложенных футур.

Нужен ли мне Dart?

Я пишу на Дарте каждый день вот уже в течение 2-х лет (https://montagebook.com) — в основном фронтенд, но есть и бекенд сервисы. В целом нравится язык, не очень нравится политика гугла по отношению к нему и его PR (никакой PR, честно говоря). Если кратко, то для меня плюсы и минусы такие:

Плюсы:

* Concurrency. В языке с самых первых версий появились Futures и Streams, и поэтому все библиотеки их используют, и не изобретают свои велосипеды. Как правило, многие библиотеки и фреймворки поддерживают асинхронность с использованием этих Futures и Streams. Например, веб-фреймворк Redstone может принимать футуру в качестве response, тогда он подождет пока она завершится и потом сгенерирует response. MySQL драйвер возвращает результаты в Stream'е, а вставляет записи возвращая Future. Практически все аналоги в стандартной библиотеке работы с файловой системой имеют асинхронные аналоги. Для браузера, все API тоже обернуты в Streams или Futures. И вкупе с тем, что сейчас в язык добавили async/await и Zones (типа Node'вых Domains, но с поддержкой глобальных переменных на уровне зоны, типа Java's thread-local storage), все это сильно упрощает написание event-based веб сервисов и построение сложных приложений в вебе. Довольно легко можно писать в FRP-стиле, т.к. дофига чего возвращает Stream.

* Тулинг. Статический анализатор (хотя язык интерпретируемый — никакого compile-time!), линтер, менеджер пакетов, приличный автоформаттер, хороший unit-test фреймворк (опять же — отлично работает с асинхронными тестами), и еще куча всего. IDE работает хорошо, go to definition, find usages, рефакторинг, все это есть. Статический анализатор особенно хорош — это по сути headless IDE. Благодаря анализатору, я, например, сделал crossdart.info, который содержит исходники SDK и всех пакетов из центрального репозитория и ссылки между ними (например, crossdart.info/p/sdk/1.12.1/async/future.dart.html#line-182), а также хромовый плагин, который добавляет «go to definition» и «find usages» функциональность в пулл реквесты на гитхабе — ( crossdart.info/demo.html ), очень удобно теперь делать код ревью на проекте.

* Нормальная семантика языка (в отличие от JavaScript) — lexical scope, strong typing, вывод типов (локальный, правда), классы/интерфейсы/джереники (дженерики правда на уровне классов, не методов, тут TypeScript рулит больше)

* Довольно легко дебажить — дебаггер работает в IDE более-менее хорошо (особенно в серверных приложениях, с браузером бывают глюки), есть Observatory — инструмент для профайлинга и дебага уже работающих процессов — можно подключиться к процессу и поставить брейкпоинт, посмотреть CPU или Memory profile, посмотреть метрики, и пр. Довольно просто дебажить даже асинхронный код — благодаря зонам, если обернуть асинхронный кусок в Chain.capture из пакета stack_trace, то можно получить нормальный читаемый стек трейс даже в коде, состоящем из одних коллбеков и футур.

Минусы:

* Язык довольно консервативен, хочется больше современных плюшек, типа type aliases, non-nullable types, method generics, immutable value objects — вот этого всего. Справедливости ради, они вроде начинают копать в сторону non-nullable types и method generics.

* Никакой PR со стороны гугла, плохая репутация, маленькое коммьюнити. Гугл довольно активно использует Dart для внутренних нужд, и вектор развития языка похоже сильно смещен на удовлетворение нужд внутренних гугловых команд (Ads, Angular, и прочих).

* Нету консольного REPLа, нету горячего обновления кода.

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

Akka, акторы и реактивное программирование

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

Типы и функции

Только не конструкторы типов, а конструкторы значений (value constructors). Конструктор типов — это Bool

Будущее JavaScript MVC фреймворков

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

Опубликован исходный код Light Table

Пока что лучшая IDE для ClojureScript. Поиск по документации, инлайн доки, jump-to-definition, возможность прямо-вот-тут-в-коде выполнить тут же написанные функции в контексте подсоединенного браузера — все это работает прямо из коробки. Красота!

Уведомления о завершении консольных команд

В MacOSX можно делать так: «sleep 3; say 'completed'». Если у вас, конечно, звук включен.

Сервис Payoneer

С апреля этого года уже если за 50$k переваливает — то нужен паспорт сделки.

Ovi Maps 3D

Оказывается, Nokia не только увольняет. На Ovi maps она даже набирает — careers.stackoverflow.com/jobs/11365/software-testing-engineer-with-scripting-skills-nokia

Про фрилансера Ивана и как он не вставал с дивана

А вот про это мне было бы очень интересно почитать. Пишите, уверен, многие найдут это интересным и полезным.

Про фрилансера Ивана и как он не вставал с дивана

Это да, но когда я выбирал банк, я выбрал тот, что через дорогу от дома. Если перееду — то просто переведу паспорт сделки в другой банк. Который тоже по возможности будет через дорогу. А переезды, думаю, не так часто случаются.

Про фрилансера Ивана и как он не вставал с дивана

Ну в первый раз действительно непросто. А потом в общем-то за час все это провернуть. Предположим, вы работаете на иностранного заказчика, он каждый месяц шлет вам деньги. У нас уже есть акты за прошлые месяцы, все необходимые документы из банка за прошлые месяцы. Поэтому:
1. Меняем дату и сумму в акте, шлем заказчику на подпись
2. Заказчик подписывает акт, отсылает назад, также отсылает деньги.
3. Когда приходят деньги, банк присылает письмо-уведомление, подставляем во всех справках/документах данные из уведомления (там в основном даты и суммы, в общем-то можно даже скриптик накатать, который это делать будет, потому что уведомления все шаблонные)
4. Печатаем все эти документы, несем в банк к валютному контролю. Он продает валюту на рублевый счет с транзитного, можем сразу там же деньги сразу снять.
Все. Потратить час-два раз в месяц, зато получать честную и белую зарплату. А это тоже важно, потому что:
а) без хорошей зарплаты в Европу/США и другие страны, где виза нужна, визу скорее всего не дадут.
б) кредит тоже не взять, а без кредита купить что-то большое (например, дом/квартиру) не реально
в) да и как-то спокойнее, когда знаешь, что ты живешь по закону и ничего не нарушаешь

Про фрилансера Ивана и как он не вставал с дивана

Дык писали же уже на эту тему: habrahabr.ru/company/moedelo/blog/53221/

Волшебная коробочка

Time Machine на нее бэкапится прекрасно!

«Я не пишу юнит-тесты, потому что ...» — отговорки

По TDD — сначала тест не должен пройти — он должен быть красным. После того, как вы добавите код, запустите еще раз тест — он должен быть успешен. Таким образом если у вас он до написания кода зеленый, или после написания кода красный — значит тест не правильный (при условии что код верен).

Программист, который отвлекается

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

Очень хорошо эта техника работает во время приближающихся дедлайнов — очень высокая производительность. Но лично для меня так работать все время тяжело.

Программист, который отвлекается

25 минут работаем, 5 отдыхаем. Получается 30 минут — это одна помидора. :) Перед работой составляем план со списком заданий, каждое задание оцениваем в помидорах — сколько помидоров требует это задание. Потом ставим таймер на 25 минут — делаем задание, потом 5 минут отдыхаем, 25 минут работаем, 5 отдыхаем, таким образом выполняя задания, один за одним. В процессе отмечаем сколько нам потребовалось помидор для выполнения задания, и сколько мы планировали.

Это в кратце. Подробнее тут — http://www.pomodorotechnique.com

Ruby on Rails 3 — Заметки к финальному релизу

А у меня не получилось переехать на Rails 3, уткнулся в это:
https://rails.lighthouseapp.com/projects/8994/tickets/5557-rails-300-yield-wont-show-block-contents-in-render-layout-if-it-is-placed-after-render-partial
Надеюсь, скоро починят…

Вышел Vim 7.3 public beta

Да это просто праздник какой-то! Сохраняющийся undo и colorcolumn. Ееееее! :)

Видео-капча от NuCaptcha

 Мне больше нравятся другие каптчи — например, negative captcha (идея, пример реализации в виде Rails плагина). Несравненно большее удобство для пользователя (потому что она вообще не заметна для него) при немного меньшей, возможно, эффективности.

Информация

В рейтинге
Не участвует
Откуда
Palo Alto, California, США
Дата рождения
Зарегистрирован
Активность