Сырая мысль, зародилась только что. Современные средства рефлексии (reflection), будь то средства дотнета, джавы или скриптовых языков, идеологически предназначены для анализа реализации (т.е. получения ответов на вопросы "каков тип объекта, какие методы есть у объекта, какие параметры у метовод" etc.)
Представляется интересным некоторое средство анализа архитектуры (ответы на вопросы вроде "что инкапсулирует этот объект — данные или действие? если данные, какова их модель? какова идеология доступа? если действие, каковы его пред- и пост-условия? с какими объектами взаимодействует этот объект?" и т.п.)
Пример в псевдокоде (Ruby-образном, как водится):
def report_formatter(arg)
assert arg.meta.designed_as(Data)
case arg.meta.data_model
when Array: #выводим списокwhen Matrix: #выводим таблицу when Tree: #выводим деревоwhen SingleValue: #просто печатаем значениеend
end
При этом, "архитектурная рефлексия" позволяет униформно работать с совершенно разными данными, соответствующими модели Array: и с индексируемыми числом (например arg.size, arg[i] — или же arg.children.get_count, arg.children.get_by_index(i) ) и с внешним итератором в стиле C++, и с внутренним итератором и yield — функции report_formatter это просто по-ба-ра-ба-ну.
Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
Боюсь, что проблемы в 'а ведь достаточно описать "модель" библиотеки'. Например, в ADO.NET курсор отсутствует в принципе.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
ЗХ>>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
IT>Боюсь, что проблемы в 'а ведь достаточно описать "модель" библиотеки'. Например, в ADO.NET курсор отсутствует в принципе.
Ну, я к сожалению не знаю, как там все организовано (иначе мог бы чего-то конкретное сказать). Но вообще курсор — это даже больше к реализации относится. А "модель данных" — это просто "последовательность значений". Последовательность может быть реализована как курсор, или просто массив, или...
Здравствуйте, IT, Вы писали:
ЗХ>>А как там в ADO.NET все это выглядит?
IT>Одноразовый рекордсет с возможностью пробежаться в одну сторону.
Ну, под концепцию "последовательность значений" это все равно подходит.
Другое дело, что пример демонстрирует: в реальной жизни вместо красивого набора 5-6 "ключевых моделей" опять возникнут "последовательность с односторонним итератором, двусторонним, восьмиугольным; read-only, с возможностью модификации" и т.п.
Тем не менее, так хочется чего-то такого...
def function(arg)
data = arg as Concept::Sequence
data.each#bla-bla-bla
#а может быть даже
data.iteration_type #forward, biderectional, random
data.modifiable #true, false
#...end
Короче, такой идеологический рефлекшен.
Теоретически, даже и библиотеку такую можно написать под какой-нито язык. Но для каждого нового типа данных придется заново определять его "привязку" к концепциям — а это геморрой.
Я, собственно, почему на эти темы задумался. Потому что юниксоидные утилиты, известные мощностью своей интеграции, обменивались нетипизированным текстом. В этом была их сила (любая утилита могла взаимодействовать с любой, в крайнем случае через какой-нибудь фильтр); в этом же была их слабость (ну, чем слабы нетипизирвованные языки, сами знаете).
А хочется, хочется объединить силу обоих подходов: взаимодействие всего со всем без потери идеологии типов.
То есть, возможности писать что-то вроде:
Если результат выполнения команды load_db_table дает объект с методами size, [] ; а print_report ожидает объекта с методами first, next, last — то ничего не попишешь.
Чего мне хотелось — возмоности проверить правильность "идеологии" полученного объекта — но игнорировать его конкретный интерфейс.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>А хочется, хочется объединить силу обоих подходов: взаимодействие всего со всем без потери идеологии типов. ЗХ>То есть, возможности писать что-то вроде: ЗХ>
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>А хочется, хочется объединить силу обоих подходов: взаимодействие всего со всем без потери идеологии типов. ЗХ>>То есть, возможности писать что-то вроде: ЗХ>>
Хорош над маленьким смеяться
Ну а что xml-то? Тоже ведь — один сервис вернет один xml, другой ожидает другой, единственный выход — xsl писать (ручками опять же). Думаешь, легче будет?
IT>>Например, в ADO.NET курсор отсутствует в принципе.
ЗХ>>А как там в ADO.NET все это выглядит?
IT>Одноразовый рекордсет с возможностью пробежаться в одну сторону.
А в чем принципиальное отличие от курсора? Односторонность?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
Ключевые слова: "обратная трансляция".
... << RSDN@Home 1.2.0 alpha rev. 643>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
ГВ>Ключевые слова: "обратная трансляция".
Можно подробнее? Гугление по ключевым словам ничего не дало, ассоциативная память тоже молчит
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
ГВ>>Ключевые слова: "обратная трансляция".
ЗХ>Можно подробнее? Гугление по ключевым словам ничего не дало, ассоциативная память тоже молчит
Можно, конечно. Я имею ввиду попытку восстановить исходный текст программы по её объектному коду.
Проблемы примерно такие. Ситуация: выделяем место на стеке. Вопрос: зачем? Это два int или один double? Или вообще — один alloca()? А уж если оптимизатор склеил хвосты функций... А ещё наинлайнил... А ещё исключения намешались... А ещё виртуальные функции подменены инлайновыми...
Насколько я знаю, пробовали для этих целей делать экспертные системы, но не слишком преуспели. Если сам язык иногда ещё можно опознать по характерным последовательностям вызова функций, то что на нём должно быть написано... у-у-у... Закончилось, кажется, тем, что генерировали паскаль и С с ассемблерными вставками.
В объектном коде нет той информации, которая нужна человеку, но вовсе не нужна машине. Потому трудно восстановить представление на языке высокого уровня. Собственно, в той задаче о которой ты говоришь, будет та же самая проблема, что и при обратной трансляции, только выражаться она будет другими словами. Например, может статься так, что "курсор" будет представлен вовсе не "курсором", а "итератором" набора данных. Да и тот может оказаться собирательным понятием. Вроде одиозной "парадигмы". Не все же одинаково смотрят на программу — некоторые могут оперировать набором мелких сущностей для эмуляции "больших". Иногда так даже удобнее: не писать кучу самосинхронизированных объектов, например, а просто семафор и блокируемый объект сопроводить комментарием: "захватить семафор перед использованием объекта, кто не спрятался — я не виноват". Разработчику этого будет достаточно, а автоматическому анализатору — нет. Ну или придётся следовать каким-то предопределённым терминам, сиречь, получится очередной "стандартный интерфейс", специально для автоматического анализатора.
... << RSDN@Home 1.2.0 alpha rev. 643>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ЗХ>>>>Зачем это все нужно? Например, для легкой интеграции разнообразных библиотек без толстого-толстого abstraction layer. Например, для работы с БД есть ODBC, есть Perl::DBI и т.п. — а ведь достаточно описать "модель" библиотеки "эта функция требует на вход путь к БД и возвращает объект с моделью данных Курсор". Точнее, модель-то можно описать и сейчас. Как можно прикрутить к C++ и даже к C какую-то рефлексию. А хочется — некоего "рантайма", в котором все это происходило бы само собой.
ГВ>>>Ключевые слова: "обратная трансляция".
ЗХ>>Можно подробнее? Гугление по ключевым словам ничего не дало, ассоциативная память тоже молчит
ГВ>Можно, конечно. Я имею ввиду попытку восстановить исходный текст программы по её объектному коду.
ГВ>Проблемы примерно такие. Ситуация: выделяем место на стеке. Вопрос: зачем? Это два int или один double? Или вообще — один alloca()? А уж если оптимизатор склеил хвосты функций... А ещё наинлайнил... А ещё исключения намешались... А ещё виртуальные функции подменены инлайновыми...
Ну, это-то понятно. Но я имел в виду не внешний инструмент, а какую-то (среду? язык?), которая при написании программы включала бы метаинформацию такого рода (как CLR включает информацию для "обычной" рефлексии).