Язык программирования Свойства, которые облегчают рефакторинг? - PullRequest
7 голосов
/ 10 июня 2009

Каковы общие черты / свойства языков программирования, которые облегчают (упрощают) разработку широко автоматизированных инструментов анализа и реинжиниринга (преобразования) исходного кода?

Я в основном думаю о функциях языка программирования, которые облегчают разработку инструментов статического анализа и рефакторинга (т. Е. Сравнивают Java с C ++, первый из которых лучше поддерживает рефакторинг).

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

Например, для Ада есть ASIS :

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

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

См. Также FAQ по ASIS

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

Я думаю о конкретных методах реализации для обеспечения низкоуровневых хуков, например, о функциях базовой библиотеки, которые обеспечивают способ проверки AST или ASG во время выполнения.

Ответы [ 7 ]

6 голосов
/ 11 июня 2009

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

2 голосов
/ 14 июня 2009

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

2 голосов
/ 14 июня 2009

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

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

Что делает анализируемым язык программирования, так это инфраструктура предназначен для поддержки анализа . ASIS Ады выше, отличный пример. Не путайте тот факт, что ASIS был написан для Ады или является написано в аде; важно то, что кто-то серьезно хотел проанализировать Ада и приложил усилия, чтобы построить анализ Ада техника.

Я считаю, что правильным решением является построение инфраструктуры общего анализа. и амортизировать его на многих языках. В то время как мы на этом, мы должны построить общую инфраструктуру преобразования, тоже, потому что, как только у вас есть анализ, вы захотите использовать это, чтобы произвести изменение. (Визиты к врачу не заканчиваются диагнозом; они заканчиваются лечением). И я поставил на это свою карьеру.

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

Он имеет общий синтаксический анализ, построение дерева, красивую печать, манипулирование деревом, перезапись от источника к источнику, атрибут оценка грамматики, контроль и анализ потока данных. У этого есть производственные качественные интерфейсы для многих широко используемых диалектов C и C ++, для Java, C #, COBOL и PHP, и даже для Verilog и VHDL (также много других языков, но не совсем на этом уровне).

Чтобы дать вам некоторое представление о его полезности, он был использован преобразовать код JOVIAL для бомбардировщика B-2 в C ... без нас когда-либо видел исходный код. См http://www.semdesigns.com/Products/Services/NorthropGrummanB2.html

Теперь, если предположить, что у человека есть инфраструктура анализа, на каком языке Возможности помощи?

Статические типы помогают, ограничивая набор возможных значений, которые может принимать переменная, но только путем добавления ограниченного предиката с одним аргументом, например, «X является целым числом». Я думаю , что помогает больше - это утверждения в коде, потому что они фиксируют предикаты с более чем одним аргументом, которые устанавливают отношения между переменными состояния, которые часто не могут быть найдены путем проверки код (например, информация о проблеме или домене, например, «X> Y + 3».) Инфраструктура анализа (и, честно говоря, программисты, которые читают код) в идеале может воспользоваться такими дополнительными фактами, чтобы обеспечить более эффективный анализ.

Такие утверждения обычно кодируются специальными ключевыми словами, такими как «assert», «pre (условие» и «post (условие»), которые вдохновлены веской причиной из теоремы, доказывающей литературу.

Но даже если у вас нет утверждений на вашем языке, они в любом случае его легко закодировать: просто напишите оператор if с условием, содержащим отказ в утверждении, и тело делает что-то, что вызывает идиому невозможность или нарушает семантику языка (например, разыскивать явно нулевой указатель), такие как "if (x> 0) fail ();"

Так что на самом деле нужны не утверждения на языке, , а программисты кто готов их написать . Увы, этого, к сожалению, не хватает.

1 голос
/ 14 июня 2009

Существует парадигма «код - данные». Например. каждая строка кода - это просто данные с точки зрения этого языка. Это делает рефакторинг таким же базовым действием, как примитивные операции с данными. И название этого языка - Лисп. ;)

Если серьезно, то "язык для программирования" и "язык для машины" - это два разных требования. И идеальный язык для анализа может стать кошмаром для программиста. Более того, язык, предназначенный для некоторого анализа, может вообще не быть языком программирования. (На прошлой неделе я познакомился с языком для анализа указателей, и у него нет текстового представления и только два исполняемых оператора)

И снова: сначала вы должны определить задачу, а затем решить ее. Например: если задание «Я хочу писать безопасные программы, например, я хочу быть уверен, что я никогда не буду пытаться смешивать целочисленные и символьные операнды», то вам нужен язык со статическими типами. Хорошо, «мне нужно знать во время выполнения, что я могу сделать с внешними библиотеками» - рефлексия - ваш выбор. «Мне нужен универсальный язык программирования для обмена, преобразования и анализа» - скорее всего, это не то, что вы действительно хотите.

1 голос
/ 10 июня 2009

Отражение встроено в систему языка / типа. Это делает статический анализ и рефакторинг гораздо менее болезненным.

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

Кроме того, вы также можете анализировать ваш скомпилированный код.

0 голосов
/ 15 июня 2009

ИМО самым важным свойством является то, что язык полностью указан и детерминирован. Например, в C поведение следующего кода не определено языковой спецификацией:

x++ = x++ + ++x;

Если поведение кода не определено, но все же он компилируется и выполняет что-то , не существует безопасного способа его автоматического изменения (т.е. рефакторинга) таким образом, чтобы это что-то * 1007 сохранялось *.

Следующее важное свойство заключается в том, что оно не разрешает доступ к переменным (полям) за пределами его области видимости. Указатели делают это возможным, например, в C, чтобы получить доступ к значению любой переменной, просто «угадав» адрес. В таком языке есть случаи, когда невозможно определить, где в коде значение определенной переменной считывается и / или изменяется. Опять же, не существует безопасного способа автоматического рефакторинга программы, которая может сделать что-то подобное.

0 голосов
/ 14 июня 2009

Для рефакторинга: самоподобие

Способность принимать трансплантаты кода без навязчивых изменений или странной реинтерпретации. Примеры:

  • Извлеките фрагмент кода C ++ в новую процедуру, используя ссылочные параметры для предоставления ей доступа к переменным.
  • Методы Python, Javascript и Lua на самом деле являются просто функциями, имеющими параметр self. *
  • На любом количестве языков функция, которая создает / заполняет структуру, может быть (более или менее тривиально) преобразована в конструктор.

Контрпримеры ...

  • Ruby (модули, классы), методы лямбда-блоков и необработанные блоки: различия в семантике, по меньшей мере, сбивают с толку. (это все, что я могу сказать наверняка.)

Для (на мой взгляд) совершенно другого случая автоматического искажения я гораздо менее уверен, но на самом деле это свобода от побочных эффектов, предлагаемых функциональными языками программирования. (Хорошо, так как же мы можем предложить то же самое на языке для всех остальных?)

* Питон почти такой. (Я забыл, что такое гоча. Вероятно, что-то связано с тем, если метод был определен в классе или на него наложено время выполнения.)

...