Написание сложных проектов на динамическом языке
От: mkizub Литва http://symade.tigris.org
Дата: 25.12.08 12:57
Оценка: +1 -1
При написании большого проекта на динамическом языке встаёт вопрос о надёжности кода.
Особенно когда проект начинался как небольшой по размеру, и вполне себе справлялся с работой по автоматизации внутренних нужд, но перерос в большой публичный код, используемый сторонними пользователями. Которые, разумеется, жаждут стабильности и минимума багов.
Конечно, все ошибки автоматически найти не получится, и в программах на статически типизированных языках тоже есть ран-тайм проверки и ошибки. Но их там намного меньше, или, по крайней мере, можно изменить программу так, что большинство из них будут отловлены на стадии компиляции.
А как это сделать в динамических языках — я себе не могу представить.
Есть ли подобные средства для них и как они работают?
Насколько у вас возрастают затраты времени на сопровождение при росте размера проекта и публичном использовании?
Есть ли какие-нибудь динамические языки, код которых можно аннотировать типами (и другими констрайнтами), позволяющими плавно перейти к верифицируемому коду?
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re: Написание сложных проектов на динамическом языке
От: Lloyd Россия  
Дата: 25.12.08 13:12
Оценка:
Здравствуйте, mkizub, Вы писали:

M>А как это сделать в динамических языках — я себе не могу представить.

M>Есть ли подобные средства для них и как они работают?

pylint?
Re: Написание сложных проектов на динамическом языке
От: Курилка Россия http://kirya.narod.ru/
Дата: 25.12.08 13:26
Оценка:
Здравствуйте, mkizub, Вы писали:

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


Erlang? Python3k? (с последним почти не знаком)
Re: Написание сложных проектов на динамическом языке
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 15:23
Оценка: 6 (1)
Здравствуйте, mkizub, Вы писали:

M>А как это сделать в динамических языках — я себе не могу представить.


Очень просто. Заменяем проверки компилятора юнит-тестами.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[2]: Написание сложных проектов на динамическом языке
От: mkizub Литва http://symade.tigris.org
Дата: 25.12.08 15:59
Оценка: -2
Здравствуйте, AndrewVK, Вы писали:

M>>А как это сделать в динамических языках — я себе не могу представить.


AVK>Очень просто. Заменяем проверки компилятора юнит-тестами.


Не понял. Как можно юнит-тестом протестировать, что функция принимает на вход только аргументы определённого типа (структуру, набор данных гарантированно имеющих поля с этими именами и этими типами данных)?
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[3]: Написание сложных проектов на динамическом языке
От: Гест Украина https://zverok.github.io
Дата: 25.12.08 16:13
Оценка: +1
Здравствуйте, mkizub, Вы писали:

M>>>А как это сделать в динамических языках — я себе не могу представить.


AVK>>Очень просто. Заменяем проверки компилятора юнит-тестами.


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


На уровне отдельной функции можно протестировать, что:
а) приняв на вход корректные данные, она отработает
б) приняв на вход некорректные данные, она обязательно вылетит (если это необходимо); с разумным предупреждением (если это необходимо); оставит окружающую среду в констинентом состоянии (если это необходимо)
Re[4]: Написание сложных проектов на динамическом языке
От: mkizub Литва http://symade.tigris.org
Дата: 25.12.08 16:30
Оценка: -2
Здравствуйте, Гест, Вы писали:

Г>На уровне отдельной функции можно протестировать, что:

Г>а) приняв на вход корректные данные, она отработает
Г>б) приняв на вход некорректные данные, она обязательно вылетит (если это необходимо); с разумным предупреждением (если это необходимо); оставит окружающую среду в констинентом состоянии (если это необходимо)

Нельзя. Потому как эта функция вызывает другие функции, в зависимости от входящих аргументов и глобального состояния программы. Все возможные состояния программы проверить тестами невозможно, их слишком много.
И потом, даже если крыть всё тестами, то это на порядок больше работы (если не на два), по сравнению со статической типизацией, например.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[5]: Написание сложных проектов на динамическом языке
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 20:19
Оценка: +1
Здравствуйте, mkizub, Вы писали:

M>Нельзя. Потому как эта функция вызывает другие функции, в зависимости от входящих аргументов


Юнит тестирование как раз таки и характеризуется тем, что тестируется не программа целиком, а ее маленькие модули.

M> и глобального состояния программы.


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

M> Все возможные состояния программы проверить тестами невозможно, их слишком много.


Невозможно. И статическая типизация их тоже не все проверяет, а только определенный набор правил, описываемых контрактами, контроллирует. А сложность контрактов в современном статическом мейнстриме все еще совсем невелика.

M>И потом, даже если крыть всё тестами, то это на порядок больше работы (если не на два)


Не на порядок, и не на два, а процентов на 30-50 по оценкам. И не стоит забывать, что статическим языкам тесты тоже небесполезны.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[3]: Написание сложных проектов на динамическом языке
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 20:19
Оценка:
Здравствуйте, mkizub, Вы писали:

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


А что тут неочевидного? Передать не тот тип аргументов и убедится, что это приводит к ошибке.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[3]: Написание сложных проектов на динамическом языке
От: Nuald Россия http://nuald.blogspot.com
Дата: 26.12.08 04:13
Оценка:
Здравствуйте, mkizub, Вы писали:

AVK>>Очень просто. Заменяем проверки компилятора юнит-тестами.


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


Python: isinstance, hasattr — как раз для такого рода проверок.
Re[4]: Написание сложных проектов на динамическом языке
От: mkizub Литва http://symade.tigris.org
Дата: 26.12.08 10:02
Оценка:
Здравствуйте, Nuald, Вы писали:

AVK>>>Очень просто. Заменяем проверки компилятора юнит-тестами.


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


N>Python: isinstance, hasattr — как раз для такого рода проверок.


Ясно. Полное непонимание сторон
Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?
Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[5]: Написание сложных проектов на динамическом языке
От: Nuald Россия http://nuald.blogspot.com
Дата: 26.12.08 10:10
Оценка:
Здравствуйте, mkizub, Вы писали:

M>Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?

M>Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?

Покрыть юнит-тестами все точки входа в функцию. При стопроцентном code coverage (хе-хе) все будет ровно. Вопрос тока как его получить?

Если интересует супер-крутое верифицируемое программирование, советую ознакомиться с Praxis’ Correctness by Construction development process. Вот это реально круто, хотел бы я в таком поучаствовать и поплевать во всякие питоны и руби с большой колокольни
Re[5]: Написание сложных проектов на динамическом языке
От: Гест Украина https://zverok.github.io
Дата: 26.12.08 10:26
Оценка: +1
Здравствуйте, mkizub, Вы писали:

M>Здравствуйте, Nuald, Вы писали:


AVK>>>>Очень просто. Заменяем проверки компилятора юнит-тестами.


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


N>>Python: isinstance, hasattr — как раз для такого рода проверок.


M>Ясно. Полное непонимание сторон

M>Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?
M>Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?

— Здравствуйте, это молоток, им забивают гвозди
— Нет-нет, вы мне объясните, как этим молотком шуруп закрутить?

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

А еще, вы знаете, в динамических языках даже бывают функции, могущие принимать на вход аргументы разных, зачастую несвязанных типов. Полиморфизм называется.
Re[5]: Написание сложных проектов на динамическом языке
От: VoidEx  
Дата: 26.12.08 11:16
Оценка:
Здравствуйте, mkizub, Вы писали:

M>Ясно. Полное непонимание сторон

M>Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?
M>Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?
Никак. Только на всякий случай уточню, что принадлежность к какому-либо типу не столь уж сильный контракт, а вот как можно гарантировать, что функция в ран-тайме получит на вход только int x такой, что x > 6 и list<int> l такой, что l.length() < x?
Re[6]: Написание сложных проектов на динамическом языке
От: mkizub Литва http://symade.tigris.org
Дата: 26.12.08 11:49
Оценка:
Здравствуйте, VoidEx, Вы писали:

M>>Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?

VE>Никак. Только на всякий случай уточню, что принадлежность к какому-либо типу не столь уж сильный контракт, а вот как можно гарантировать, что функция в ран-тайме получит на вход только int x такой, что x > 6 и list<int> l такой, что l.length() < x?

Ну, типы — это наиболее частый контракт. Если есть варианты проверить и другие — тоже хорошо.
Как доказать? Очевидно, аннотациями и соответствующими верификаторами (в том числе и умеющими выводить нужную информацию из control/data flow).
Ясно, что проверить всё на свете не получится, да это и не надо. Просто хотелось-бы потерять ощущение ходьбы по минному полю.
Пока программа (на javascript, кстати) была не очень большой — она обозревалась легко. А теперь хотелось бы, чтоб компьютер мне мог помочь в ходьбе по этому минному полю.
Давали ссылки на erlang — прошерстил и нигде не нашёл ничего соответствующего.
На python3k — тоже только планы по введению опциональной аннотации типами, а в доке на него ничего не нашёл.

У меня же на руках есть SymADE, я думал — если нет ничего вообще из подобных верификаторов, то может имеет смысл загнать в него онтологию javascript-а, и написать свой верификатор. Но только я ума не приложу как это вообще верифицировать, если в любом момент можно загнать в объект новое поле или метод или поменять им тип... Я думал, посмотрю на эти существующие верификаторы и возьму у них идею как они это делают. Для того и спрашиваю.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[5]: Написание сложных проектов на динамическом языке
От: Mamut Швеция http://dmitriid.com
Дата: 26.12.08 13:56
Оценка: 1 (1) +1
M>Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?

Некриворуким программированием.

Грубо говоря:
точка входа в программу
    |
    |
     - func1(string)
           |
           |
            - func2(int)


в момент входа в func2 мы должны уже знать, что входящий параметр — int. И не париться Это не так сложно, как кажется


ЗЫ. Также не надо ассоциировать статическую типизацию со строгой, а динамическую — со слабой


dmitriid.comGitHubLinkedIn
Re[3]: Написание сложных проектов на динамическом языке
От: targeted Россия http://www.targeted.org/
Дата: 03.01.09 08:09
Оценка:
> Не понял. Как можно юнит-тестом протестировать, что функция принимает на вход только аргументы определённого типа (структуру, набор данных
> гарантированно имеющих поля с этими именами и этими типами данных)?

Возможно использование декораторов и (в Python 3.0) аннотаций:
http://code.activestate.com/recipes/572161/

Для Python 2.x аналогичный декоратор выглядит менее красиво, но работает примерно так же:
http://code.activestate.com/recipes/426123/

Результат, кстати, получается с гораздо более широкими возможностями, нежели просто проверка типов компилятором.
Необходимость unit-тестов при этом все равно не исчезает.
Re[5]: Написание сложных проектов на динамическом языке
От: targeted Россия http://www.targeted.org/
Дата: 03.01.09 08:30
Оценка:
M>Ясно. Полное непонимание сторон
M>Я спрашиваю — как юнит-тестом можно гарантировать/протестировать, что функция в ран-тайме получит на вход только аргументы определённого типа?
M>Не то, что она кинет ошибку, а то, что она не получит неправильных данных — как?

Так и в языке со статической типизацией, гарантировать, вообще говоря — никак. Ибо зачастую в нем присутствуют способы принудительного приведения типов, которые позволяют успешно прострелить себе ногу, несмотря на старания компилятора.
Например:

void foo(Bar*);
Biz* biz = new Biz();
foo((Bar*)biz);

и т.п. Так что, как говорил Остап Бендер, гарантию дать может только страховой полис.
А насчет "как протестировать" уже было сказано.
Re[6]: Написание сложных проектов на динамическом языке
От: VoidEx  
Дата: 03.01.09 09:45
Оценка:
Здравствуйте, targeted, Вы писали:

T>Например:


T>void foo(Bar*);

T>Biz* biz = new Biz();
T>foo((Bar*)biz);

А на Хаскеле такое же прокатит?
Re[7]: Написание сложных проектов на динамическом языке
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.01.09 09:49
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, targeted, Вы писали:


T>>Например:


T>>void foo(Bar*);

T>>Biz* biz = new Biz();
T>>foo((Bar*)biz);

VE>А на Хаскеле такое же прокатит?


unsafeCoerce?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.