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

Original author: Matthew Butler
  • Translation
Я люблю Dart, это очень мощный язык для написания как клиентской, так и серверной части. На нём можно создавать и html-странички и html-игры, с использованием только DOM или с использованием WebGL/Canvas. Можно писать консольные текстовые игры, однажды, я создал на Dart многопользовательскую консольную игру, которая работала через telnet. Я использовал этот язык для создания скриптов, опроса и управления удалённым оборудованием и хранения результатов в БД, на основе которых можно было потом получить красивые графики.

Но Dart не панацея и отвечая на вопрос в заголовке статьи: всё зависит от того, что нужно сделать. Например, вы не можете написать на нём операционную систему. Вы не можете получить ту же производительность что даёт C при написании игр(тех, что не для браузера). Он не оптимизирован для обработки больших научных данных. Dart это просто инструмент со своим назначением. Вы же не станете ловить акулу сачком для бабочек.

Javascript может делать всё то же самое, что и Dart. И у JS есть преимущество в количестве готовых библиотек. Я бы советовал их избегать при изучении JS, использование библиотек новичками может привести к тому, что потенциальный программист будет знать как писать на jQuery, но не как на JS, и в конечном итоге к плохой производительности разработанных сайтов. Мне уже доводилось исправлять подобные работы.

При использовании только стандартных библиотек Dart имеет преимущество перед JS прямо из коробки. Многие API уже учитывают различия в браузерах, в то время как JS требует индивидуального подхода(к счастью сейчас это уже не такая большая проблема, которой она была когда Dart только вышел). Функционал стандартных библиотек в Dart даёт такие возможности, которых нет в чистом JS и для получения которых нужно использовать сторонние библиотеки. Которые могут конфликтовать между собой или изменять поведение JS таким образом, что другие библиотеки станут вести себя непредсказуемым образом.

У Dart с конфликтами всё проще. Во первых, самих библиотек меньше, а во вторых есть стандартные механизмы обхода конфликтов. В меньшем количестве библиотек есть и свои плюсы, например, вам нужно рассмотреть меньше разных вариантов чтобы подобрать именно тот, что подойдёт вашему проекту.

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

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

В конце хотелось бы отметить, что опытные разработчики, с которыми я разговаривал, выбрали Dart в пользу JS по той причине, что сам язык и его стандартные библиотеки решают те ключевые проблемы, которые им мешали при использовании других языков. Будь то механизм наследования в JS или нестандартное поведение области видимости или длительные итерации кодинга-компиляции. Опытные программисты выбирают Dart из-за тех преимуществ, которые предоставляет этот язык. Это мои личные предпочтения в языке программирования.

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

P.S. Я невероятно пристрастен относительно Dart. Я могу с уверенностью сказать, что моя жизнь изменилась благодаря Dart. Всё потому, что я был одним из первых, кто внедрил язык в рабочий процесс, я был в сообществе с самого его начала, и получил такие возможности, которых не было бы без Dart. Я сделал свой вклад в SDK и документацию на начальной стадии. У меня был шанс попасть на собеседование на должность, связанную с Dart, и в данный момент полный рабочий день я работаю с этим языком.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 16

    +15
    Вода водой.
    К переводчику претензий нет.
      +1
      Да, вода водой. Можно заменить Dart на ClojureScript или Elm и т.п. — все говорят одно и тоже: «нас мало, зато у нас очень дружелюбное комьюнити профессионалов и мы компилируемся в кроссбраузерный js, не нужно думать о совместимости».
    • UFO just landed and posted this here
        +1
        Про библиотеки речь наверное о том, что хорошо когда стандартная библиотека языка достаточно богата и концептуально согласованна с парадигмой самого языка(в Dart'e все то для чего обычно используют jQuery доступно из стандартной библиотеки dart:html).

        Я тоже сильно расстраивался из-за прекращения развития Dart Editor.

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

        И их логика в прекращении развития собственной IDE мне видится такой: ресурсы разработчиков ограничены и тратить их на разработку и поддержку еще одной IDE не особенно интересно, по факту большинство из тех кто использует Dart достаточно опытны чтобы установить плагин в любимую среду разработки и настроить ее. Вот они и сосредоточились на разработки качественных инструментов поддержки разработки, типа профайлера, автоформатера кода, менеджера пакетов и т.д. которые могут быть встроены в разные IDE и просто редакторы типа Sublime или Atom.
        • UFO just landed and posted this here
          • UFO just landed and posted this here
          0
          + для самых простых опытов(если код использует только стандартные библиотека) можно использовать DartPad
          +1
          В меньшем количестве библиотек есть и свои плюсы, например, вам нужно рассмотреть меньше разных вариантов чтобы подобрать именно тот, что подойдёт вашему проекту.

          О как. А если вообще нет, еще лучше? Совсем не нужно искать.
            +3
            У нас уже есть одна C#/Java, который компилируется в JS (и это я не про GWT), LISP, который компилируется в JS, престарелая помесь бульдога с носорогом, которая тоже компилируется в JS и молодая помесь xml с JS, которая опять таки компилируется в JS. У нас есть даже JS, который компилируется в другой JS!

            А для создания скриптов и бэкенда у нас есть всё то же самое, плюс Python/Ruby/PHP/C#/Java.
              0
              Что-то не врубаюсь, кто бульдог с носорогом. Большинство остальных перечисленных извращений уже пробовал — но, кажется, что-то пропустил.
                0
                CoffeeScript.
                  0
                  А, спасибо. Тогда всё в порядке, и это немножко пробовал. Сингулярность какая-то, 6 лет с первого релиза — а и правда уже престарелый.
              +3
              Я пишу на Дарте каждый день вот уже в течение 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а, нету горячего обновления кода.

              В целом, язык дает довольно неплохой баланс между строгостью языка, легкостью освоения и доступными инструментами.
                0
                Вы не могли бы пояснить примером кода, как вот это
                Довольно просто дебажить даже асинхронный код — благодаря зонам, если обернуть асинхронный кусок в Chain.capture из пакета stack_trace, то можно получить нормальный читаемый стек трейс даже в коде, состоящем из одних коллбеков и футур
                — можно сделать?
                  +1
                  Пусть у нас есть куча вложенных футур:

                  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
                  


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

              Only users with full accounts can post comments. Log in, please.