Лучший ответ
-
0 0
wad (56) 7 (37983)3824 13 лет
излишняя функциональность для ленивых студентов. Use the force, Luke!
Ответы
-
1 1
Russia86 7 (28167)635116 13 лет
Итак, как же будет выглядеть дизайн решения задачи Problem K (http://thesz.livejournal.com/280784.html) в случае Эрланга. Для начала разберемся, какие возможности в плане декомпозиции нам дает Эрланг.
В Эрланге, собственно говоря, есть два основных инструмента для структурирования системы. Первое — модули, второе — процессы. Процесс с точки зрения дизайна является прямым аналогом ООП-шного _объекта_. Он полностью удовлетворяет букве и духу определения объекта Алана Кея. Он имеет состояние (на стеке в бесконечной рекурсии), имеет идентити (pid()), посылает и отправляет сообщения другим процессам, а также сам решает, как обработать полученное сообщение. Кроме того, если сравнить процессы Эрланга с объектами Smalltalk 72, мы получим _полнейшую_ идентичность. Системы не похожи — они просто одинаковы. В случае Эрланга мы, правда, имеем добавочные свойства в виде распределенности, изоляции, и отказоустойчивости. Но это в контексте нашей темы — неважно.
Итак, процессы в Эрланге могут применяться (и применяются) в тех же контекстах и с теми же целями, как объекты в ООП. Кроме того, процессы в Эрланге могут применяться и по другому — как эквивалент техники декомпозиции программы на ленивых списках (потоках) в чистых языках. Таким образом, процессы в Эрланге обеспечивают большую гибкость при декомпозиции задачи, и являются редкой техникой, сочетающей свойства как "потокового" dataflow дизайна, традиционого для "чистых" языков, так и ОО дизайна. В курсе SICP авторы отмечали, что задача "подружить" два этих "ортогональных" подхода — это сложная и актуальная теоретическая проблема. Так вот, процессы Эрланга (а точнее — actors model) — это ее решение, это более общий механизм.
Однако, мы не будем их применять при решении нашей задачи — неспортивно это, и ограничимся применением модулей. Потому, что мы хотим от нашего решения функциональной чистоты. В этом случае, оно будет идиот... (черт, какие умные слова ты употребляешь, thesz!) идиоматическим не только для Эрланга, как хотел thesz, но также для большинства функциональных языков.
Так вот, модуль — это очень простая штука. Это файл, единица раздельной компиляции. Он имеет имя. Он может экспортировать определенные в нем функции. Они вызываются вот так: module_name:function_name( arg1, ..., argN ). И все.
Таким образом, задача дизайна для нас сводится к очень простой штуке. Надо побить наше решение на модули, таким образом, чтобы связность между ними была настолько слаба, насколько это возможно. Да, важный момент — никакого "состояния", в отличии от классов, модули не инкапсулируют. Это просто некоторая именованная группировка функций.
Как мы можем уменьшить связность между модулями? Это, право же, просто. Воспользуемся концепцией "абстрактного типа данных". Суть состоит в том, что мы будем прятать структуры данных за функциональными интерфейсами. Ну-с, приступим-с. Начнем с наиболее простого и очевидного — бинарных операций. Их неплохо бы завернуть в отдельный модуль — если я сделаю это правильно, то я смогу попросить, скажем, potan-а, добавить новую операцию не заставляя его разбираться с моим дизайном, и он это сделает очень быстро, совершенно не забивая голову никаким дизайном. Собственно, это основное свойство хорошего дизайна.