вторник, 19 августа 2014 г.

Ссылка. Пишем простой интерпретатор на C++ с помощью TDD

http://habrahabr.ru/post/231657/

На хабре чувак пишет интерпретатор с помощью TDD на С++.

По-моему - отличная статья.

Что особенно понравилось это - The Transformation Priority Premise (TPP)

Прям процитирую:

"Сам список трансформаций:

  1. ({} → nil) Заменить отсутствие кода на код, использующий нулевое значение.
  2. (nil → constant) Заменить нулевое значение константой.
  3. (constant → constant+) Заменить простую константу более сложной (строку из одной буквы на строку из нескольких букв, к примеру).
  4. (constant → scalar) Заменить константу на переменную, или аргумент.
  5. (statement → statements) Добавить безусловный оператор (break, continue, return и подобное).
  6. (unconditional → if) Разбить поток выполнения с помощью условного оператора.
  7. (scalar → array) Заменить переменную/аргумент массивом.
  8. (array → container) Заменить массив более сложным контейнером.
  9. (statement → recursion) Заменить выражение рекурсией.
  10. (if → while) Заменить условный оператор циклом.
  11. (expression → function) Заменить выражение функцией.
  12. (variable → assignment) Изменить значение переменной.
"
Скажем так - я интуитивно это понимал и сам использовал на уровне "подсознания", но вот так чётко и ясно - формулировку увидел впервые.

И вообще - мне сильно понравилось, что автор "практически формально" применяет подход - тест -> падает -> трансформация -> тест не падает -> рефакторинг -> тест не падает.

"Формально" то "формально", но автор - добивается цели. И вполне успешно.

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

Но теперь я нашёл обоснование для своей "работы на уровне подсознания".

Частично этот подход был описан вот тут - Тестируем калькулятор №6.2.1. Применяем "классическое TDD".

Не знаю как это оценит аудитория, но мне лично кажется, что "The Transformation Priority Premise (TPP)" - это "бомба". Не "серебряная пуля" конечно, но бомба.

Понятное дело, что любой инструмент можно извратить и применять неправильно, но если обладать определённым "опытом" и "чутьём", то действительно можно писать код и тесты - "чисто формально". Не поймите меня неправильно.

Теперь о "вопросах к автору".

Они - конечно же есть.

Самый волнующий меня вопрос - это почему операторы представляются enum'ами с char-константами. В духе:

enum class Operator : wchar_t {
    Plus = L'+',
    Minus = L'-',
    Mul = L'*',
    Div = L'/',
    LParen = L'(',
    RParen = L')',
};

- меня это лично несколько "шокирует".

Но учитывая, что я встречал этот подход не раз и в частности у Антона Григорьева в его "парсере формул" и во множестве статей и книг, то мне кажется, что это некая такая "best practice", о которой я не в курсе.

Теперь о Хабре и "комментариях".

Прямо слово - комментарии "доставляют".

Есть конечно комментарии полезные и умные. О них я говорить не буду.

А есть такие за которые "глаз зацепился". О них скажу пару слов.

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

Итак:

Самое что "впечатлило", это конечно:
Программа будет писаться в Visual Studio 2013

Дальше не читал…

-- хочется сказать - "молодец, самовыразился за счёт автора".

Но зачем автору и другим читающим этот комментарий? Какая от него практическая польза?

Надо отдать должное автору, который очень вдумчиво и корректно ответил:

Всё то же самое можно сделать в Eclipse с установленным плагином C/C++ Unit, скачать Boost.Test, или GTest, скомпилировать их, прописать в путях проекта. Но в таком случае половина статьи будет касаться только настройки окружения. В Visual Studio 2012 и 2013 окружение, готовое к TDD создаётся за пару кликов. Хотя, для написания более сложных тесто, всё равно придётся ставить Boost.Test, или подобное.

-- в общем - респект автору.

Далее.

Вот комментарий:
TDD и прочие практики экстремального программирования мне всегда казались извращением

Ну "кажутся извращением", так зачем читать? Ну не убедил автор в "своей религии", ну и что? Провоцировать его "на дальнейшую работу" над "извращениями"? Ну может быть.

Но опять же автор статьи на высоте:
Рекомендую к прочтению книгу Agile!: The Good, the Hype and the Ugly Paperback – Bertrand Meyer, 2014. В ней как раз даётся разбор, что из XP хорохо, а что не очень. TDD не является серебряной пулей, но зачастую является очень полезной техникой.

Ну и ещё из комментариев:
Вроде все хорошо, но почему строки по значению передаете?
А большинство push_back можно заменить на emplace_back.

Напоминает "студента", который узнал о "best practice" и пытается всем показать, что он "это знает".

Понимаете в чём дело? Ведь автор наверное не просто так это всё писал и наверное думал о чём пишет.

Это напоминает "всем известные" споры о FreeAndNil, возникающие в контексте различных статей, которые вроде бы и не о FreeAndNil.

И ведь если бы автор стал бы в статье разбирать "эту тему", то его бы оправданно обвинили бы "отходе от темы".

Тем более, что "передача по значению vs. передача по ссылке" в C++ это сложная и объёмная тема. Которая выходит далеко за рамки статьи. В этой теме даже корифеи - "до конца не договорились".

И есть множество статей на тему - "почему надо данные передавать по значению".

Учитывая наличие в C++11 конструкторов с &&.

Но надо отдать должное автору - он и тут на высоте:
Ближе к концу строки передаются по константной ссылке, emplace_back также появляется немного позже.

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

- в целом там комментарий хороший и вдумчивый.

Но хочется отметить вот что - ведь автор не пишет статью о том "как писать парсеры или интерпретаторы". Он ведь на примере "интерпретатора" пытается показать применение TDD. А это - несколько другой коленкор.

Т.е. комментарий вообще-то хороший, правильный. На тему "парсеров". Но не совсем в "тему статьи".

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

Ну вот "я так вижу".

Комментариев нет:

Отправить комментарий