Javascript умирает или перерождается?

Original author: PÉTER HALÁCSY
  • Translation
Заранее прошу прощения за некоторые обороты в переводе. Буду рад услышать здравую критику и поправки, лучше в пм. Спасибо. – пер.

Стартапы имеют много общего с JavaScript'ом. Когда вы только начинаете, вам нужно быть динамичными. Вы должны быть гибкими. Вы должны иметь возможность мгновенно выпустить прототип, который просто работает, и вам нужно уметь быстро и дешево менять его без перекомпиляции вашего кода. JavaScript появился когда война между браузерами только начиналась, и он раздавил Java и Flash по тем же причинам, по которым стартапы рушат рынки и вытесняют признанных игроков: быстрота и гибкость.

Сегодня JavaScript уже не стартап, и не только стартапы его используют. Компании всех размеров и уровней зрелости делают приложения для браузера, и JavaScript — это язык, который они используют для этого. Претензии, которые были однажды предъявлены таким языкам, как C/C++ и Java, сейчас предъявляются JavaScript'у, и эти претензии относятся к ограничениям языка: производительности и поддерживаемости.

Последнее поколение JavaScript движков достигло невероятных высот производительности, но этого все еще недостаточно. Посмотрите на такие сайты, как YouTube и Hulu, или игровые платформы Facebook'а или EA. Когда нужно сделать мультимедийное приложение, компании все еще обращаются к производительности Flash. Провидение Стива Джобса могло предсказать судьбу, которая в итоге постигнет Flash, но нам еще приходится работать с ним, пока JavaScript не дотягивает по производительности.

Как только объем вашего кода достигает сотни тысяч строк, и он весь написан на таком динамичном языке, как JavaScript, скорость разработки начинает страдать. Если вы делаете изменения где-то в одной части кода, нет никакой возможности узнать, что это не приведет к багам где-то еще, не запуская приложение. Тестирование может только усугубить ситуацию – привести к большому количеству непредвиденных расходов, сделанных заранее. Результат — больше багов в приложении либо же более длинные циклы разработки.

Кто-то должен что-то сделать с этими ограничениями, чтобы компании могли вводить новшества и делать удивительные приложения для веба. Кто же собирается сделать это и как?

Prezi, LogMeIn и Ustream организовали MLOC.js, конференцию, сфокусированную на том, как улучшить JavaScript. Инженеры из Google, Facebook, Mozilla, Groupon, и других компаний, работающих над серьезными техническими задачами собрались на три дня в Будапеште для обсуждения как они справляются с ограничениями JavaScript. Их работа даст уверенность, что JavaScript не единственная жизнеспособная платформа в будущем, но первая, которая изменит наше представление о том, как писать приложения в вебе.

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

Это мне говорит о том, что нет одной серебряной пули, которая решит эти проблемы, но может быть множество, которое решит. JavaScript — это динамический язык, который превосходен в склеивании веба, и это неизменно.

Бизнес-логика должна работать, и должна работать корректно. Статический анализ в таких системах, как Dart или TypeScript, важен, для гарантии, что наиболее чувствительные компоненты нашего приложения работают – и продолжат работать, когда наши приложения вырастут и эволюционируют. Нам нужно больше таких инструментов для статического анализа. Тем не менее, если посмотреть на рынок браузеров, непохоже, что мы увидим широкое распространение нативной поддержки этих технологий в ближайшее время.

Оказывается, что нативная поддержка для новых языков не всегда обязательна. Alon Zakai из компании Mozilla говорил об ASM.js, подмножестве JavaScript'а, который выполняется очень быстро на современных браузерах без модификации. Когда имеет значение скорость, нам стоит писать на ASM.js. Или, еще лучше, мы можем писать наш код на C и иметь компилятор, генерирующий ASM.js для нас. Если не говорить о производительности, мы можем применить эту технику к другим языкам и в других вариантах использования. Разработчики почти сделали это, и все их усилия перечислены на atl.js.

Один из лучших способов сделать ваш код более поддерживаемым – это писать меньше кода. Библиотеки вроде bacon.js или язык Elm кратко выражают сложные зависимости данных в вашем приложении и выгружают работу по сохранению актуальности данных в библиотеку. Результат – меньше кода для поддержки и более высокое качество приложений.

JavaScript никуда не уходит, но подвергается трансформации. Разработчики создают вариации языка и впечатляющие библиотеки для лучшей обработки специфических вариантов использования, включая производительность. Вдобавок, есть прогресс и в создании инструментария и статическом анализе. Все эти тренды влияют на то, как мы пишем приложения для веба. Конференция MLOC.js многое прояснила.

Для больших игроков, тех, кто использует JavaScript каждый день, только один вопрос остается открытым: что вы сделаете для того, чтобы JavaScript стал наиболее гибким, производительным и масштабируемым языком, который мы когда-либо знали?
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 64

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

    Хотим рыбку съесть и косточкой не подавиться.
    Что же последнее время все так всполошились из-за гибкости языков? Ну нельзя же создать идеальный яп, всегда будут какие-то минусы и какие-то плюсы. Всегда найдется яп над яп, который генерирует родительский яп при компиляции, и выглядит лучше.
      –12
      Лично я мечтаю о том, чтобы JavaScript наконец закопали (при моей жизни желательно) и заменили если не на что-то из моих любимых строготипизированных функциональных языков, то хотябы на тот же TypeScript или Dart. Не хочу обидеть адептов JavaScript, скорее всего моих мозгов просто не хватает чтобы понять всю его красоту, но лично для меня он входит в список языков (вместе с ещё одним очень популярным), на котором я категорически не хочу программировать только если совсем жизнь не заставит (хотя уже приходилось пару раз) или пока кто-то не предложит за это ну очень-очень хорошую оплату. В то же время я нахожу концепцию принятой в JavaScript модели асинхронности на коллбэках весьма красивой.
        0
        В JavaScript прорва возможностей — он действительно очень гибок. Мое личное мнение — надо использовать свой набор библиотек под конкретный проект, и принимать определенные Code Style Conventions. Но, конечно, в моих проектах никогда не было миллиона строк кода =)
          +2
          Мне честно жаль, что для вас это так, ведь динамическое предопределение методов, выполнения метода в нужном контексте и многое другое, мммм.
            –7
            За «выполнения метода в нужном контексте» и вообще за нелексические замыкания js закопать надо.
              0
              okay.tiff
                +5
                Не вводите людей в заблуждение. Замыкания в JavaScript как раз лексические.
                А вот контекст и вправду динамический. Но как только ты об этом узнаеш, вся магия исчезает. Это фича JavaScript.
                  –7
                  Я и не говорил, что магия. Только это, по-моему, тот случай, когда все-таки не фича, а баг.
                    +4
                    Очень даже фича, с динамическим контекстом можно творить много интересных вещей (делать примеси, например)
                  0
                  нелексические замыкания

                  Извините, это что за зверь такой? Особенно учитывая, что сам термин «замыкание» является сокращенным варинатом термина «лексическое замыкание».
                    0
                    Некорректно сформулировал, имел ввиду динамическое изменение контекста.
                +1
                Мне тоже нравятся строготипизированные функциональные языки, и именно поэтому я люблю JavaScript. Ведь до недавнего времени только на JavaScript (среди прочих мейнстрим языков) можно было хоть как-то писать в функциональном стиле (функции как сущности первого порядка, замыкания).
                Боюсь что еще нескоро такие языки как OCaml, Haskell, даже Scala, получат значительную долю на рынке.
                  0
                  Вот Scala — моя любовь :-) Почти мой идеал если бы ни некоторые особенности JVM.
                  –1
                  В соседнем топике картинка, очень хорошо отражающая моё отношение к JavaScript. В то же время есть один всем известный язык, вызывающий у меня гораздо более глубокий ужас, уж лучше JavaScript. Но это, повторюсь, моё личное субъективное впечатление.
                  0
                  Встроить надежную виртуальную машину в браузеры на клиентах, разрабатывать на удобном языке, клиенту передавать байт-код.
                    0
                    А чем Javascript не подходит в качестве своеобразного байт-кода? Пишите компилятор любимого языка в JS — и вперед. Собственно, так и делают — что Coffeescript, что Dart, что Typescript.
                      0
                      Для библиотек-то это, вестимо, покатит, но скриптовые вставки к этим библиотекам обращающиеся внутри страницы же всё-равно на голом JavaScript придётся писать, не?
                        0
                        хоть немного крупные(больше вызова функции) вставки внутри страницы — зло
                        +1
                        Во-первых, миллион строк кода лучше передавать в виде байт-кода, а не исходников на JS. Во-вторых, два уровня виртуализации — не есть хорошо для производительности. И что касается производительности, в-третьих, в JS динамическая типизация, в VM же можно добавить команды и для динамической, и для статической типизации.

                        Просто нет лидера, который бы волевым решением это вытянул, вопреки стандартам и традициям, как это случилось с HTML5.
                          0
                          Ну, по поводу что некому вытянуть — вроде как Гугловский JavaScript-движок становится стандартным JavaScript-движком в составе WebKit (раньше там, вроде, «из коробки» какой-то другой свой был, который использовался в Safari). А если так, то все браузеры на WebKit (коих вроде уже большинство), автоматически получат поддержку Dart. Не?
                            0
                            по вроде не :(
                            v8 это не дартовая машина(пока)
                            0
                            По поводу байт-кода: в JavaScript-коде могут использоваться текстовые идентификаторы элементов, определённых в HTML и CSS коде. Что с ними-то делать тогда?
                              0
                              Если в случае «произвольный язык — язык виртуальной машины — машинный код» два уровня виртуализации, то в яве и дотнете тоже тогда два, и я не понимаю, как это изменится в случае появления некоего байт-кода, и как это повлияет на увеличение производительности. Сейчас javascript вполне можно считать языком виртуальной машины (в V8, например, он сразу компилируется в машинный код при первом запуске, минуя байт-код).

                              Динамическая типизация — да, но в том же V8 накладные расходы, связанные с ней, возникают только в момент добавления свойств в объекте (в этом случае генерируется новый класс), доступ к свойствам реализуется точно так же, как и в случае со статической типизацией. Создавайте все свойства объекта сразу, используйте функции-конструкторы, и будет вам счастье.

                              Ну, размер js-кода, конечно, больше размера аналогичного байт-кода, это да. Но это сомнительный повод для создания еще одного слоя.
                          +34
                          Странные вещи высказаны в статье, Откуда-то на клиенте взялась бизнес-логика на js в 100000 строк, Я, честно, говоря не видел пока клиентских браузерных проектов таких объемов, Во-вторых, что за странная убежденность, что статическая типизация хоть в каком-то виде спасает от проблем в масштабных проектах? Тысячи проектов бажных на C++ тому пример, более того не спасает даже дополнительный статический анализ кода (почитайте Джона Кармака о его энтузиазме и разочаровании в статическом анализе C++ кода), В подобных проектах проблемы связаны не с языком, а с архитектурой приложения, инфраструктурой тестирования и т.д. Вся проблема, описываемая в статье, возникает из ложного посыла о том, что динамическая природа языка — источник всех бед, Меня, честно говоря, сильно раздражает раздутая паника вокруг js (и ее производные в виде TypeScript), т.к. сам прошел все эти стадии в начале своей карьеры программиста. И именно поэтому считаю подобный подход незрелым, Я начинал изучать программирование C/C++ еще в школе, на работе познакомился с C# и первое время JS меня раздражал, Я просто его не понимал, Совершенно, Весь мой языковой кругозор ограничивался императивными статически-типизированными языками и больше для меня мира программирования не существовало, С таким кругозором JS мне казался шуткой, девиацией, Я настолько его ненавидел что на рабочем столе у меня была фотография Брендана Ахо с нецензурной подписью, Подобную же реакцию я испытал, например, по отношению к Lisp, когда познакомился с ним в университете, Но я нашел в себе силы (а вернее меня вынудила работа =)) все таки углубится в JS, И мое мнение изменилось, Этот язык не идеален, как и все в этом мире. Но преодолев порог вхождения («где классы?», «фу прототипы», «фу динамическая типизация» и прочее) я чувствую себя как рыба в воде, Мне очень нравится гибкость языка, возможность буквально заниматься «лепкой» кода, т.к. в js я не так сильно ограничен синтаксисом, как в статически-типизированных языках, Я вижу в нем свою элегантность, Перейдя через эту «гору ненависти к JS» в свое время я открыл для себя другой мир программирования, где не IDE диктует мне мышление, не язык, а мышление определяет мой образ действий, Моя «программисткая ксенофобия» прошла, С этим ощущением я решил дать второй шанс Lisp и открыл для себя мир функционального программирования, я вернулся к C и мне теперь он во многом нравится на много больше C++, Я осознал, что восприятие ООП, как панацеи от всего наивно, Мне все еще нравится C#, но теперь я вижу сколько оверинджиниринга и бутстрап-кода приходится в нем писать, что бы поддержать эфимерную парадигму, Наверно, главное чем мне нравится JS — это его выразительная способность, У Эдварда Тафти в книга есть понятие DataInk приминительно к аналитической графике (чарты, инфографика и прочее), DataInk — это отношение чернил, используемых для отображения полезной информации, информации при потере которой, график перестанет выполнять свое информационное предназначение к общему количеству чернил, использованных для отображения графика, Чем ближе это значение к 1, тем лучше, Для кода я бы ввел такую же характеристику DataCode — отношение кода, который выражает непосредственно решение задачи ко всему написанному коду, Так вот, это значение у JS ближе к 1, нежели у многих других языков, Тоже касается C (его я тоже люблю=)), В общем, к чему все это эссе: не существует серебрянных пуль, изучайте разные языки, вникайте в их дизайн, ищите плюсы и минусы и научитесь их использовать себе во благо. Не стройте себе тюрьму из предубеждений и не пытайтесь все новое запихать в узкую коробку, в который вы сидите, Возможно, то что вы так не любите, является ключом в целый новый мир (правда при условии, что вы перестанете пытаться запихать его себе в задницу, вместо замочной скважины =))
                            +9
                            Один из тех случаев, когда комментарий интереснее статьи.
                              0
                              отношение кода, который выражает непосредственно решение задачи ко всему написанному коду, Так вот, это значение у JS ближе к 1, нежели у многих других языков

                              А у декларативных/функциональных языков оно тогда ещё лучше единицы получается, выходит?
                                +2
                                Оно не может быть больше единицы, исходя из определения, Вообще, у байт-кода нативного оно ближе всего к единице, поэтому, это конечно не самая объективная характеристика языка, но одна из возможных, если брать в расммотрение еще читаемость кода, но этом контексте к JS вроде бы никто не предъявлял притензий, Если отвечать конкретно на ваш вопрос, то все зависит от языка, Например, в LISP (и производных, например Scheme и т, д, — да оно близко к единице, в силу легкого синтаксиса, возможности создавать необходимые для задачи DSL на лету и в общем открытости в сторону мултипарадигменности, т, е, рамки смягчены лепи что хочу), а вот в Haskel дела уже хуже, что является обратной стороной его формалистического функционального подхода (где, извините, без монады даже пукнуть нельзя), Но опять таки не стоит все это воспринимать как характеристику, позволяющую отделять хорошие языки от плохих, Как раз интересно искать плюсы в языках и минусы, в нашем своеобразном и разноплановом мире у всего есть своя ниша, даже у Visual Basic ;), имеющая свое право на существование, Даже экзотерические вещи, вроде Brainfuck находят свое практическое приминение (например, в llvm для примера реализации языка с использованием инфраструктуры используется как раз Brainfuck. А что? Синтаксис минималистичен, язык Тьюринг-полный, да и известен более или менее для обучения самое то. Вот дабы не быть голословным: https://github.com/earl/llvm-mirror/tree/master/examples/BrainF), Что-то я сегодня многословный =)
                                  0
                                  даже у Visual Basic ;)

                                  Начинал как раз со всевозможных Basic-ов, попрограмиировал, наверно, на почти всех его сортах ещё под DOS (и даже уже в этом году VBScript приходилось использовать), но сейчас затрудьняюсь сказать зачем нужен VisualBasic когда есть C#, разве что для кого-то он, может, кажется более «тёплым-ламповым». И уж особенно «задержавшимся на этом свете» видится VBA.
                                +3
                                Соглашусь с вышесказанным.
                                Начинал в студенчестве с C++, затем работал на пхп, после чего писал на C#, а теперь использую на руби и кофескрипт.
                                Побывал фактически с обеих сторон баррикад (хотя есть ещё мечта с эрлангом поработать). Так вот, слова о том, что компилятор и статическая типизации сильно помогают кому-то от ошибок, вызывают лишь недоумение. Если у вас компилируется программа, это означает лишь то, что вы научились грамотно писать на синтаксисе данного языка. И всё, больше это ничего не гарантирует. А умение грамотно писать автоматом приходит где-то через месяц-два работы на новом для вас языке, после чего этап компиляции приносит лишь весьма длинную и совершенно ненужную паузу перед запуском проекта или тестов. Да, тестов, т.к. — это единственное мне известное, что может хотя бы кое-как гарантировать, что ваш промышленный код работает как задумано. Если вы конечно не работаете на НАСА и не пишете на чёрт-знает-чем-с-математическим-доказательством-корректности-кода, производя в месяц несколько сотен строк кода.
                                А если вы на том же javascript пишете что-то сложнее нескольких обработчиков на jQuery, то тут могут и должны писаться тесты, для которых уже существуют на данный момент технологии(ещё пару лет назад с этим было гораздо хуже), позволяющие запускать js тесты как из консоли, так и на билд-сервере.
                                  +1
                                  Так вот, слова о том, что компилятор и статическая типизации сильно помогают кому-то от ошибок, вызывают лишь недоумение.

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

                                  Представьте себе какую-нибудь нетривиальную программу, например, просто вызов метода с аргументом: f(x). Если типизации нет, то и выжать из этого кода ничего больше нельзя. Если же имеется типизиция, то это о многом говорит. Скажем, если f : Int -> Int и x : Int и уже понятно, что функция целочисленная, а аргумент — число.

                                  Другой вариант: generic-функция f : List<T> -> List<T>, в этом случае читатель может сразу заключить, что поскольку функции не важен тип элементов списка-аргумента, то она и не опирается на значения отдельных элементов, манипулируя ими как абстрактными единицами данных, указателями, если хотите. Тогда можно предположить, например, что f(map(m, x)) делает то же, что и map(m, f(x)), где m : T -> T есть функция любого конкретного типа T или generic, модифицирующая отдельный элемент списка, а map поднимает модификацию до всего списка, аналог Select в C#. Такого нетривиального умозаключения нельзя сделать для нетипизированного языка, потому что там никогда не понятно, на что опирается функция, а на что нет.

                                  Не заглядывая в спецификацию, нельзя сказать, что функция делает; но глядя на тип, можно сказать, что функция не делает. Читателю это помощь, компилятору — подсказка, IDE — пояснение, что может желать программист. Программист же получает, помощь со стороны IDE, настраивает дружеские взаимоотношения с компилятором и будущим читателем. Кроме того, сразу отсекаются те ошибки, причина которых лежит в неправильном изложении мысли человека на используемом ЯП; другие ошибки по-прежнему останутся. Это в теории; на практике, как известно, бывает по-другому.
                                    –1
                                    но сложнее понимать, что хотел сказать программист тут или там.

                                    Для этого есть документация, например *doc. То есть оставляем и синтаксическую гибкость, и семантическую простоту. В войне static vc dynamic наиболее оптимален, по-моему, по читаемости в этом отношении PHP как ни странно с его type hinting. В сигнатуре функции или метода мы опционально описываем типы параметров, получая документирующие плюсы статической типизации, но в теле пользуемся динамической, получая её плюсы.
                                  +2
                                  Класс! Здорово сказано.

                                  А я вот никогда на типизированных языках и не писал и вообще не понимаю, о чем хомяки плачат — ну нужна тебе проверка — ну оберни ты в декоратор метод и проверть что он у тебя там получает. Это реально нужно настолько редко, что просто не о чем говорить. И тестами прокрой. Все.
                                  Хороший код можно писать на чем угодно и типизированный язык не гарантия хорошего кода. Все дело в программере.
                                    +1
                                    Таким образом ошибку получишь на этапе исполнения, возможно через долгое время после деплоя/релиза. А при статической типизации тебе сразу компилятор укажет где метод вызывается с другой сигнатурой.
                                      0
                                      Ага, правда в половине случаев придется кастовать, потому что «ну так надо» и придумывать велосипеды, как бы эту проверку побороть.
                                      И потом, если что-то не покрыто тестами и вылезло в деплое — ССЗБ.

                                      Исчо раз повторяю — если нужна проверка типов — заверни в аспект. Если нужнен конкретный тип — заверни в аспект.

                                      В 80% случаев мне нужна гибкость.
                                      Обычно мои методы ловят массив или скаляр, который заворачивают в массив — вуаля, понятный интерфейс готов.
                                      Хошь foo('bar'), хошь foo(['fizz','baz']).

                                      Кроме того, вся эта магия с типами будет работать только внутри MS-го варианта. Как только ты сделал из своего кода либу и упаковал в JS — пуффф, магии больше нет. И отгруженная либа, которую вызывает кто-то еще в JS-е становится нифига не безопасна, а вот если все в аспектах было — все ок, аспект он и в Африке аспект.

                                      Этож очевидный косяк.
                                        –1
                                        Я совмещаю динамическую и статическую типизацию (вернее её подобие) — вполне нормально. А вот заворачивание в аспекты или декораторы в теории выглядит красиво, но на практике еще тот гемор.
                                          0
                                          Практика заворачивания в аспект — github.com/Meettya/clinch/blob/master/src/file_processor.coffee#L42

                                          rejectOnInvalidFilenameType = (methodBody) ->
                                            (filename, cb) ->
                                              unless _.isString filename
                                                return cb TypeError """
                                                          must be called with filename as String, but got:
                                                          |filename| = |#{filename}|
                                                          """
                                              methodBody.call @, filename, cb
                                          
                                          <..somewhere in class...>
                                          
                                          loadFile : (rejectOnInvalidFilenameType (filename, cb) ->
                                            <...method body...>
                                          )
                                          


                                          гиде гемор?
                                            –1
                                            Синтаксис непривычен, но если правильно понял семантику, то это лишь похоже на аспект. А может формально им является, но чаще понимают под ними нечто другое, не требующее изменения кода аспектируемой функции/метода, только его метаданных.
                                              0
                                              Обычный CoffeeScript синтаксис, добавьте в стакан немного скобокочек и кавычечек и получите JS.

                                              Я бы сказал это аспект в его истинной форме, после того, как какой-нить метапроцессор обработал наш исходник и вставил вызовы функции туда, где они нужны. Ведь именно это и происходит на самом деле.

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

                                              Так что если отбросить всю мишуру — это аспект. Или метод-декоратор. Оно просто работает.

                                              Таки гимор-то где? Почему эта конструкция не может быть использована там, где нам нужна проверка типов или что там еще надо проверить?
                                                –1
                                                Я опознал CoffeeScript (по расширению :), да и контексту), но в уме транслировать затруднительно, да и правил трансляции не знаю.

                                                Как мне кажется, АОП — это не использование ФВП и подобных техник, а нелокальное и независимое от аспектируемой функции изменение её поведения. Код для метапроцессора, саму функцию не изменяющий — АОкод, код после трансляции — уже не АОП-код. Как код на C++ — ООП-код (в общем), а транслированный в ассемблер- не ООП. По транслированному коду можно понять, что он хорошо ложится на АОП и/или ООП парадигму, или даже написан с её использованием, но в языке поддержки сущностей парадигмы нет, она эмулируется

                                                В данном случае не АОП потому что нам нужно вносить изменения в код каждой функции, которой внезапно понадобилась проверка на существование файла. Мы пишем «эта функция перед выполнением проверяет существование файла с помощью этого „аспекта“ в коде функции, а не „этот аспект проверяет существование файла перед выплнением этой функции“ в коде аспекта или отдельном файле метаданных. Инверсия контроля нужна, чтобы этот код стал АОП-кодом.

                                                  0
                                                  Там же есть корявый JS github.com/Meettya/clinch/blob/master/lib/file_processor.js#L57

                                                  Исчо раз — в JS можно сделать true AOP, для того есть всякие модули, но по мне вся эта фигня уменьшает читаемость кода, как и миксины. Только миксины — неизбежное зло, а вот аспекты можно и упростить.

                                                  Мысль короче такая — нафик не нужен этот TS, он замыкает на себя разработку и по факту ничего не гарантирует. Нужны проверки — их есть в JS. Все.
                                                    –1
                                                    Исчо раз — в JS можно сделать true AOP, для того есть всякие модули

                                                    Вот это я имел в виду пол гимором.
                                                    нафик не нужен этот TS

                                                    Про TS я вообще ни слова не сказал :)
                                                    Нужны проверки — их есть в JS

                                                    Но не как часть языка. Только в рантайме в общем случае можно что-то проверить.
                                                      –1
                                                      Вот это я имел в виду пол гимором.

                                                      Покажите мне из коробки AOP язык, который используется в реальности.

                                                      Но не как часть языка. Только в рантайме в общем случае можно что-то проверить.

                                                      Да и фик с ним. Ну нет проверки, все равно от нее толку мало. Пишите тесты, ставьте логгеры, проблема проще решается. Для этого не надо изобретать четырехколесного лисапеда, типа как микрософт сделали.

                                                      Ну нельзя сделать ПО безопасным, налепив на него стикер «Безопасное», как любят делать в MS. Нет серебрянной пули :)
                                                        0
                                                        Java(+Spring) :)

                                                        пишите тесты, ставьте логгеры, проблема проще решается.

                                                        Вы действительно считаете, что это проще, чем вместо function f(x) написать int function f(float x)?
                                                          +1
                                                          Java(+Spring) :)

                                                          О, там да, там офигенски все просто. Пишем простыню XML-я и все заработает. И еще фабрики фабрик фабрик.
                                                          Этой астронавтикой можно только на чужие большие бабки развлекаться, за свои уж лучше что попроще.

                                                          Вы действительно считаете, что это проще, чем вместо function f(x) написать int function f(float x)?

                                                          Оооо… Так, последний раз, мессадж такой — пока вы кодите в песочнице у вас вся эта фигня работает. И рождает чувство ложной безопсности.
                                                          Как только код становится модулем и его зовет кто-то сторонний, в реальном мире — оно становится дырявым и фейлится. Это раз.
                                                          Тесты, ассерты и т.д. писать все равно придется, их объявление типа не отменяет. Хотя, можете не писать, дело ваше.
                                                            –1
                                                            Тесты на то, что вместо float передан string и выскочило исключение писать не нужно. IDE сможет выдавать инфу о типах без лишних телодвижений. Для меня два основных плюса статической типизации или её аналогов. Чувство ложной безопасности они у меня не вызывают, но от глупых ошибок спасают.
                                    0
                                    Но преодолев порог вхождения («где классы?», «фу прототипы», «фу динамическая типизация» и прочее) я чувствую себя как рыба в воде, Мне очень нравится гибкость языка, возможность буквально заниматься «лепкой» кода, т.к. в js я не так сильно ограничен синтаксисом, как в статически-типизированных языках, Я вижу в нем свою элегантность, Перейдя через эту «гору ненависти к JS» в свое время я открыл для себя другой мир программирования, где не IDE диктует мне мышление, не язык, а мышление определяет мой образ действий, Моя «программисткая ксенофобия» прошла

                                    Какие прекрасные слова. Я действительно думал, что кто-то обнаружил способ ключ к написанию «красивого» кода.
                                    Но реальность расставила все по своим местам:

                                    github.com/inikulin/parse5/blob/master/lib/lexer.js
                                     //NOTE: iterate through states until we don't get at least one token in the queue
                                        while (!this.tokenQueue.length) {
                                            if (this.pos < this.html.length)
                                                ch = this.html[this.pos];
                                    
                                            //NOTE: treat CR+LF as single line break
                                            if ((ch === '\n' && prevCh !== '\r') || ch === '\r' || ch === '\f') {
                                                this.lineLengths[this.line] = this.col;
                                                this.line++;
                                                this.col = 1;
                                            }
                                            else if (!(ch === '\n' && prevCh === '\r'))
                                                this.col++;
                                    
                                            this[this.state](ch);
                                    
                                            prevCh = ch;
                                            this.pos++;
                                        }
                                    

                                    Это очень тяжело поддерживать. Тут и близко не лежит элегантность.
                                    Если в проекте есть несколько «таких» вот художников, то client-side превращается в АДъ
                                    Лучше все же глубже копнуть в ООП.
                                      –1
                                      Товарищ, во первых это токенизатор HTML, где впринципе по-другому особо не напишешь, а во-вторыз это не client-side, ну а в третьих ООП в это проекте как раз есть =)) Так что пальцем в небо, чувак
                                        +2
                                        Во-первых, я это увидел.

                                        Во-вторых, я не говорил что этот код находится на clientside.

                                        В-третьих, я говорил копнуть в ООП поглубже, а то что его нет.
                                        Например, комментарий поясняющий код, значит нужно выделить в метод
                                        //NOTE: treat CR+LF as single line break
                                                if ((ch === '\n' && prevCh !== '\r') || ch === '\r' || ch === '\f') {
                                        

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

                                          Спасибо, что рассказали о самодокументируемости кода, но как раз тут ничего выносить не нужно, т.к. в этом проекте я очень щепетильно отношусь к производительности, а вызов метода ради такой мелочи — аллокация нового скойпа — полная глупость. Причем, если уж вы такой любитель паттернов, то приминительно к этому случаю откройте Фаулера и найдите там про «Стрельбу по воробьям». В этом коде ровным счетом ничего экстраординарного нет, если у вас вызывает затруднение чтение такого элементарного кода, то у меня для вас плохие новости. Вот вам реализация того же лексера в Вебките github.com/WebKit/webkit/blob/master/Source/WebCore/html/parser/HTMLTokenizer.cpp (осторожно, вам может совсем поплохеть)
                                            –1
                                            Причем, если уж вы такой любитель паттернов

                                            Я не любитель паттернов, а даже наоборот. Я их противник. Но это отдельная — очень длинная история.

                                            Касательно выделение метода по условию. Это не просто самодокументируемость, это часть не останавливающегося рефакторинга. Когда вы выделяете метода, их становится сразу несколько. Затем приходит понимание о том, что пора выделить сущность. И т.д.
                                            В итоге вместо одного огромного класса, появляется несколько маленьких и простых.

                                            Почти любой код можно разобрать, вопрос времени и желания. Но я не хочу разбираться в чужом коде, а так же не хочу, что бы кто-то мучился разбирая мой код. На мой взгляд, каждый уровень абстракции должен решать конкретную задачу и должен быть полностью описан в одном месте и не занимать больше 2х экранов кода. И ООП говорит о том, как этого добиться.
                                              –1
                                              Я бы с удовольствием посмотрел на разбиение на сущности какого-нибудь токенизатора. Можно даже какого-нибудь более тривиального, буду очень благодарен за мастер класс, а то из десятков исходников, которые я изучал, нигде подобного не встречал. Спасибо, опять таки, что рассказали про непрерывный рефакторинг (которым, я кстати, и занимаюсь, если посмотреть на то, как поменялся весь этот код за последние два дня и менялся до этого), но это опять таки не имеет никакого отношения к тому, что вы написали. Очень глупо считать, комментарии в коде признаком плохого кода (а больше вы ничего конкретного расписать и не смогли). Вынесение метода работает ровно до тех пор, пока вы может придумать адекватное название для метода. Здесь не та ситуация (здесь следование четко заданное спецификации, нет никакой сакральной логики в комментированом коде, а лишь обработка ситуации, связанной с историческими причинами). В таком случае просто необходимо комментировать код. Да в общем, что тут распинаться, все эти вещи есть и в литературе и должны взвешенно откладываться в голове. Мнение «этот код плох, потому что в нем есть комментарии» просто не претендует на какую-либо состоятельность
                                                0
                                                Мнение «этот код плох, потому что в нем есть комментарии» просто не претендует на какую-либо состоятельность

                                                Т.к. мне надоела эта тема, скажу лишь то, что я полностью с этим не согласен.
                                                Удачи вам с элегантностью вашего кода без ООП, честно надеюсь, что у вас однажды все получится и об этом появится статья на хабре.
                                                Извините меня за мой скептицизм в этом вопросе, просто я ещё не видел ни разу хорошо читаемого кода не в ООП стиле, в более менее среднем проекте.
                                              –1
                                              в этом проекте я очень щепетильно отношусь к производительности

                                              Тогда не надо говорить о красоте и элегантности :) Обычно с производительностью они несовместимы. Редко когда лучше читаемый вариант является и более производительным (или жрущим меньше памяти).
                                          –2
                                          P.S. Я вам еще в карму плюнул, т.к. аргументы ad hominem в спорах о недостатках языка выдают в вас невежественного человека, а я таких не люблю.
                                            +1
                                            выдают в вас невежественного человека

                                            А мне показалось, что вы взрослый и умный человек, когда читал ваш комментарий. Игры с плюсиками и кармой этого не отменяют, но «запашок то остался».
                                            Как по мне, ваш оппонент ничего грубого/неадекватного не сказал. А наоборот — проявил интерес, посмотрел GItHub. Вы бы лучше ему кусок элегантного кода показали. Дискуссия же.
                                          –2
                                          >> динамическая природа языка — источник всех бед
                                          Есть динамика, а есть каша из вроде-бы-типов и неявных приведений. Второе — та чудовищная часть JS, которую нужно закопать. После этого на нем можно будет писать.
                                            +1
                                            Вы б статью написали.
                                            +1
                                            Если вы делаете изменения где-то в одной части кода, нет никакой возможности узнать, что это не приведет к багам где-то еще, не запуская приложение. Тестирование может только усугубить ситуацию – привести к большому количеству непредвиденных расходов, сделанных заранее. Результат — больше багов в приложении либо же более длинные циклы разработки.


                                            Всегда думал, что тестирование, как раз наоборот сводит возможность что где то что то отвалиться к минимуму… Неоднозначная статья.
                                              +4
                                              А мне в js не нравится слово function.
                                                0
                                                В таком случае, CoffeeScript — это то, что вам нужно.
                                                  –1
                                                  А мне не нравится function, но и значки типа -> тоже не нравятся :( def или fn меня бы устроили :)
                                                0
                                                В яваскрипте уже есть типизованные массивы.
                                                также есть аддоны для поддержки opencl и rivertrail
                                                зачем разрабам из интел понадобилось городить свой parallel array, если можно было использовать существующие типизованные массивы не совсем понятно.

                                                имхо далее реализуют
                                                * сахарок для типизованных массивов
                                                * автотрянсляцию яваскрипт-кода в opencl
                                                * нормальное апи для вебгл, вместо сторонних библиотек
                                                * стандартизуют webcl

                                                Также очень не хватает общего механизма доступа ко всем яваскрипт движкам, что мешает проникновению яваскрипта на платформы.
                                                А именно:

                                                1 динамически линкуемая библиотека, выполняющая поиск и иницииализацию яс движков ставится на компьютер
                                                2 все движки реализуют определённый стандартизированный интерфейс
                                                3 программист подключает корневую библиотеку и выполняет функцию инициализации
                                                4 библиотека ищет движки, опрашивает их и выбирает предпочтительный, который поддерживает функции, указанные программистом, среди движков с одинаковым функционалом предпочтение отдаётся тому, который указал программист, например можно указать предпочитать v8 или gecko
                                                5 программист работает с движками используя стандартизированный апи
                                                нестандартные расширения тоже можно использовать, подключив вендоро-специфический хедер
                                                6 возможно взаимодействие между движками, тоже по стандарту, например передача объектов из одного движка в другой
                                                разумеется, это неэффективно, но если позарез нужно совместить фичи 2х движков, то почему бы и нет.

                                                Всё это даст нам возможность легко, переносимо, и без дублирования интегрировать яваскрипт в приложения.
                                                То, что сейчас происходит ни в какие ворота не лезет: для того, чтобы заюзать js-движок, приходится его собирать из исходников и поставлять вместе с прогой, несмотря на том, что почти у всех на компьютере есть несколько яваскрипт движков, причём как минимум один из них последней версии, и как минимум один — устаревшая помойка, не поддерживающая современные стандарты из-за того, что у одной хорошо нам известной корпорации сместились приоритеты.

                                                Также это позволит добавить во все браузеры поддержку самых свежих стандартов, как только их поддержка появится в одном из них.
                                                  0
                                                  В яваскрипте уже есть типизованные массивы.
                                                  также есть аддоны для поддержки opencl и rivertrail
                                                  зачем разрабам из интел понадобилось городить свой parallel array, если можно было использовать существующие типизованные массивы не совсем понятно.

                                                  Rivertrail — это спецификация, позволяющая обрабатывать массив параллельно. Основа спецификации — добавление класса ParallelArray. Данные массивы имеют ряд ключевых отличий от массивов JS.
                                                  — они неизменны
                                                  — не имеют промежутков
                                                  — они могут быть многомерны, но многомерны «правильно» (к примеру, в двухмерной матрице число столбцов будет равно числу рядов).

                                                  Отсюда, всегда ваш Кэп. Причем тут типизированные массивы? Да и много ли в js возможностей параллельного выполнения кода?)
                                                  0
                                                  Пилим библиотеки, используем наиболее гибкие, используем новые парадигмы, которые повышают гибкость. Как-то так.

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