19

Я думаю, что Coffeescript - это потрясающий язык! Я искал некоторые проекты/проблемы/функции, которые добавляют статический анализ в Coffeescript. Однако после некоторых поисков я обнаружил, что Coffeescript faq и this page предполагают, что статический анализ может оказаться нецелесообразным.Статический анализ Coffeescript/Static Typechecking - Roadblocks

Мне было интересно, если возникнет фундаментальная проблема при реализации проверки статического анализа/статического типа в Coffeescript, из-за чего чего-то подобного в компиляторе еще нет?

Кроме того, это что-то, что невозможно сделать для нетривиальных проверок, но может работать только для простого анализа? Когда я говорю прямо, я имею в виду проверку тривиальных вещей, таких как: пользователь дважды определил функцию с тем же именем (в классе) или на верхнем уровне (или, возможно, на верхнем уровне в коллекции связанных файлов. Coffee) ,

Я был бы признателен, если бы кто-нибудь мог обратить внимание на некоторые примеры, которые показывают, почему внедрение статического анализа/проверки типов не является прямым или возможным/стоит потратить время?

спасибо!

+0

Как насчет запуска jshint на сгенерированных JS-файлах? Кофе компилируется в JS и JS-инструменты, которые делают то, что вы ищете, не совсем необычны. –

ответ

13

Этот ответ немного свалка мозга, так как меня это интересует. Надеюсь, поможет.

Я использую компилятор Google Closure для статического анализа кода, создаваемого CoffeeScript. У этого есть действительно хороший статический анализатор, и я не уверен, есть ли веская причина изобретать колесо здесь. Самый простой способ это просто написать аннотации вручную:

###* 
    * @param {number} x 
    * @param {number} y 
    * @return {number} 
### 
adder = (x, y) -> x + y 

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

#! {number} x {number} y @return {number} 
adder = (x, y) -> x + y 

Я уверен, что вы можете увидеть, что ReWriter довольно прост.

Быстрое примечание, прежде чем двигаться дальше. Обязательно скомпилируйте свой код с -b (голый), если вы используете его через компилятор закрытия. Компилятор закрытия довольно хорош, но он недостаточно умен, чтобы анализировать поток данных. CoffeeScript обертывает ваш код в анонимной функции по умолчанию, что приведет к отключению компилятора.

Другой вариант по тому же пути (это будет нарушать совместимость с CoffeeScript, но было бы намного круче) будет иметь кофе компилятор компилировать что-то вроде этого:

adder = (number x, number y): number -> x + y 

в JS, как это:

/*** 
    * @param {number} x 
    * @param {number} y 
    * @return {number 
    */ 
var adder = function(x, y) { 
    return x + y; 
}; 

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

Действительно, this guy оказался выполненным именно этим. К сожалению, его работа, похоже, находится в неполном состоянии.

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

ИЗМЕНИТЬ год спустя: Я просто использую машинопись в эти дни. :)

+4

Синтетический сахар для факультативного набора статистики был бы убийцей :) –

+0

@MikkoOhtamaa: Согласен. К сожалению, jashkenas, создатель CoffeeScript, довольно интенсивен, чтобы поддерживать CoffeeScript очень близко к JavaScript, и ветви языка, как правило, томятся в неясности. Мне жаль, что есть какой-то способ получить лучшее из обоих миров. – thedayturns

8

Я не эксперт в CoffeeScript, поэтому это может быть совершенно неправильный ответ, но в основном это сводится к следующему: CoffeeScript - очень выразительный язык, причем большая часть семантики динамически определяется (и, возможно,). Это во многом отличается от таких языков, как Standard ML, которые имеют гораздо более строго определенную семантику. В целом, статический анализ на языках более высокого порядка считается очень трудно. I.e., статический анализ на реальных программах более высокого порядка (Haskell, ML, особенно javascript из-за таких вещей, как eval) просто сложно, потому что поток управления намного более гибкий. Фактически, решения статического анализа для языков более высокого порядка действительно были исследованы только за последние двадцать лет или около того. (В частности, см статьи Might Мэтта на a tutorial style description of CFA.)

В основном, причины этого:

  • Для анализа, вам приходится иметь дело с проблемой выразительных семантики ближайшей образуют управление потоком вы получаете хлопание вокруг функций более высокого порядка.
  • Чтобы сделать , набрав, обычно эти языки имеют гораздо более богатый набор доступных типов. Например, есть очень типичные ситуации, когда вы пытаетесь назначить статический тип переменной в Ruby (как в C, Java, ML и т. Д.), Вы получаете ошибку, но поскольку определенные пути вашей программы никогда исполнено, все в порядке. Наряду с этим, такие языки, как Ruby others, добавляют множество неявных преобразований типов, которые действительно использовали, чтобы сделать классное программирование. Значительная работа в этой области, с которой я знакома (dynamic analysis of static types for Ruby), исходит от некоторых людей, с которыми я работаю, но, конечно, есть и другие примеры.
  • В принципе, язык используется в гораздо более динамическом образа, с гораздо более выразительных семантикой, и рассуждение о том, что статический гораздо сложнее, и склонен к неточным. Основной фронт приближения к этому (эти дни) начинает выглядеть гибридным: вы можете статически анализировать часть программы, а также требовать, чтобы программист дал некоторые тестовые примеры, чтобы сделать какой-то изысканный анализ.

Я надеюсь, что это несколько отвечает на ваши вопросы, опять же, жаль, что я не могу обратиться непосредственно прямые опасениями вашего вопроса, поскольку это относится к CoffeeScript, но есть много работы происходит в анализе таких вещей, как JavaScript прямо сейчас. Отмечу, что некоторые из реальных проблем с Javascript исходят из его странной семантики, прототипное наследование трудно обосновать, и особенноeval()! Как правило, программные анализы для этих языков налагают определенные ограничения (например, полностью исключая eval!), Чтобы сделать анализ более выполнимым!

+0

Просто для обновления в области динамических языков «typechecking»: до сих пор вы знаете о таких проектах, как TypScript и Flowjs. Ура! –

Смежные вопросы