Я люблю 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, и в данный момент полный рабочий день я работаю с этим языком.

Комментарии (15)


  1. cjmaxik
    21.10.2015 02:46
    +15

    Вода водой.
    К переводчику претензий нет.


    1. PQR
      21.10.2015 12:18
      +1

      Да, вода водой. Можно заменить Dart на ClojureScript или Elm и т.п. — все говорят одно и тоже: «нас мало, зато у нас очень дружелюбное комьюнити профессионалов и мы компилируемся в кроссбраузерный js, не нужно думать о совместимости».


  1. degorov
    21.10.2015 09:25
    +1

    При изучении библиотек может и стоит избегать, а вот при работе как-то не получается. jQuery это, безусловно, красивый стереотипичный пример, но как избежать использования драйверов для нужной тебе БД в серверном Dart, например? :)

    И зачем они убили Dart Editor? Наличие легковесной IDE для меня всегда было плюсом.


    1. ko11ega
      21.10.2015 11:21
      +1

      Про библиотеки речь наверное о том, что хорошо когда стандартная библиотека языка достаточно богата и концептуально согласованна с парадигмой самого языка(в Dart'e все то для чего обычно используют jQuery доступно из стандартной библиотеки dart:html).

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

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

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


      1. degorov
        21.10.2015 12:04

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

        Ну и что касается того, что в Dart есть всё то…, то вот например для Fullscreen API код (по крайней мере раньше, сейчас не слежу уже) компилировался в JS только с префиксом webkit и мне приходилось для FF и IE писать красоту подобного плана, втыкая её перед вызовом скомпилированного dart-файла:

            if (document.fullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
              Object.defineProperty(document, 'webkitFullscreenEnabled', {
                get: function() { return document.fullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled }
              });
              Object.defineProperty(document, 'webkitFullscreenElement', {
                get: function() { return document.fullscreenElement || document.mozFullScreenElement || document.msFullscreenElement }
              });
              document.documentElement.webkitRequestFullscreen = document.documentElement.requestFullscreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen;
              document.webkitExitFullscreen = document.exitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;
            }
        


        Понятно, что в JS для поддержки всех браузеров что-то подобное приходится писать и сейчас, но…


        1. degorov
          21.10.2015 12:10

          UPD: в последнем dart sdk та же песня…

            @JSName('webkitFullscreenElement')
            @DomName('Document.webkitFullscreenElement')
            @DocsEditable()
            @SupportedBrowser(SupportedBrowser.CHROME)
            @SupportedBrowser(SupportedBrowser.SAFARI)
            @Experimental()
          

          Такой подход мне очень VBScript напоминает ;)


    1. ko11ega
      21.10.2015 11:29

      + для самых простых опытов(если код использует только стандартные библиотека) можно использовать DartPad


  1. jaguard
    21.10.2015 10:13
    +1

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

    О как. А если вообще нет, еще лучше? Совсем не нужно искать.


  1. k12th
    21.10.2015 10:21
    +3

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

    А для создания скриптов и бэкенда у нас есть всё то же самое, плюс Python/Ruby/PHP/C#/Java.


    1. salas
      21.10.2015 20:29

      Что-то не врубаюсь, кто бульдог с носорогом. Большинство остальных перечисленных извращений уже пробовал — но, кажется, что-то пропустил.


      1. k12th
        21.10.2015 22:24

        CoffeeScript.


        1. salas
          22.10.2015 00:14

          А, спасибо. Тогда всё в порядке, и это немножко пробовал. Сингулярность какая-то, 6 лет с первого релиза — а и правда уже престарелый.


  1. Astashov_Anton
    21.10.2015 18:47
    +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а, нету горячего обновления кода.

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


    1. ko11ega
      22.10.2015 09:53

      Вы не могли бы пояснить примером кода, как вот это

      Довольно просто дебажить даже асинхронный код — благодаря зонам, если обернуть асинхронный кусок в Chain.capture из пакета stack_trace, то можно получить нормальный читаемый стек трейс даже в коде, состоящем из одних коллбеков и футур
      — можно сделать?


      1. Astashov_Anton
        22.10.2015 20:56
        +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
        


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