Как стать автором
Обновить

Комментарии 46

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

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

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

Ну, наверное не компиляции, а начала интерпретации? И откуда появилась такая уверенная характерность? Имел опыт работы со статической строгой типизацией при проектировании метамодели (~бизнес логика, метаданные — описание типов и данных, императивное описание алгоритмов их обработки) и все было отлично.

но для ее динамической интерпретации, т.е. для преобразования ее в модель предметной области

Вот тут очень хочется увидеть детальный пример. Каким образом вы из абстрактной логики, посредством метаданных, формируете конкретные бизнес-логики? Каким образом вы формируете абстрактные логики, чтобы их можно было преобразовывать к конкретным бизнес логикам? Я так понимаю это и есть суть статьи, но вы об этом ничего не сказали…

— Я так и не понял, что конкретно вы описывали. Если формальную модель метамодели, то почему нет классификации, зачем вы обязали присутствие машины состояний? Если конкретную систему, то почему не указана что это за система?

P. S. Метапрограммирование — градиент развития определенного класса задач программирования, я вам благодарен за то, что вы освещаете эту тему.
Я старался не привязать статью ни коим образом к разработкам моей компании и нашего НИИ, изложить теорию в чистом виде, даже без ссылок на реализации на конкретных языках, библиотеках, продуктах и технологиях. У нас на этом работаю коммерческие продукты, а Хабр не место для рекламы, а в исходном коде я не все могу выложить, но кое-что выложу, когда мы причешем это к состоянию, достойному для примера.

Действительно, ни какой магии нет, более того, можно привести несколько общеизвестных систем (и даже классов систем), построенных на интерпретации метамоделей, хоть мы и не рассматриваем их как типичный пример, т.к. это не прикладные системы, а системы общего пользования, но для примера они очень показательны. Веб-рбаузеры — это типичные специализированные виртуальные машины, DOM — это метамодель страницы, а страница приходит сразу с данными и метаданными (данные — это теги и контент, а метаданные — пользовательские атрибуты тегов и скрипты по их обработке). Еще примеры: электронные таблицы (в частности Excel), Matcad, другие CAD системы, снабженные внутренними интерпретаторами сценариев и широкого набора метаданных.
Программисты, которые пишут код на html + js, привязываются к бизнес-логике, а вы говорили о повышении уровня абстракции. Меня интересует конкретно этот аспект. Какими уровнями абстракции оперируют (аналитики?) вашего НИИ при разработке коммерческих продуктов, и каким образом вам удается использовать повторно метаданные и целый подсистемы.
Программисты, разрабатывающие веб-браузер не привязываются к бизнес-логике, как и программисты разрабатывающие Excel и Matcad. Эти продукты являются мета-продуктами, превращающимися в решение для конкретной задачи только в рантайме. Но все, чего я добиваюсь подобными статьями, это признания метапрограммирования дисциплиной в рамках специальности «Программная инженерия», чтобы это воспринималось как научная дисциплина, преподавалось в ВУЗах (по крайней мере, моем — КПИ), этим и обусловлен «книжный» стиль изложения, завтра же статью получат наши профессора для рассмотрения. Ну а программистам тоже полезно подниматься на подобный уровень рассмотрения. Конечно эту дисциплину нужно снабдить практическим курсом, вплоть до лабораторных работ.
Какими уровнями абстракции оперируют (аналитики?) вашего НИИ при разработке коммерческих продуктов, и каким образом вам удается использовать повторно метаданные и целый подсистемы.

Например, если нужно сделать систему по «учету рабочего времени разработчиков ПО», то повышением уровня абстракции будет система по «учету времени» и можно построить соответствующую метамодель, а еще повысив абстрактность получится система по «учету ресурсов» (время как частный случай ресурса). При этом, систему для «учета ресурсов» написать в 2-3 раза сложнее, но из нее можно сделать 20-30 систем, по учету разных типов ресурсов или выпустить ее как продукт, в котором пользователь сам задаст параметры учитываемых ресурсов. А такую систему сделать в 5-10 раз сложнее, но из нее пользователи сделают 5-10 тысяч систем и будут арендовать это решение по принципу SaaS.
Похоже что пример с браузерами не является удачным, поскольку программисты и самих браузеров и программисты html+js используют классическую подход — построение модели предметной области? И браузер не превращается в решения конкретных задач в рантайме, а исполняет конкретные задачи в рантайме. А иначе, чем Java машина хуже, gcc? Сейчас буду перечитывать статью в контексте поиска формальных границ.

Пример с учетом ресурсов — хороший, спасибо, понял).

В родном КПИ преподают Microsoft Access и MFC :(.
Программисты браузеров как раз не строят модель предметной области и браузеры уже давно превратились в виртуальные машины, не содержащие решения конкретных задач, а лишь очень абстрактных. Например, в браузере нет средства для отрисовки графиков посещаемости веб-ресурса, но есть Canvas, на котором можно можно сделать вывод любых графиков, в том числе и посещаемости ресурса. Можно решить эту задачу иначе, есть SVG, а простые графики можно отрендерить вообще тегами. В любом случае, Canvas, SVG и теги являются метамоделью для графиков посещения ресурсов.

Java, как и .NET — это виртуальные машины, исполняющие откомпилированный код, в них не обязательно происходит интерпретация метамодели в рантайме. Можно писать классически, а можно динамически, технология не предрасположена к способу. Метамодель и обработку метаданных можно частично реализовать хоть на bat-файлах или на юниксовых шел-скриптах. Например, у моего коллеги есть шел-скрипты для развертывания БД с динамическим формированием SQL-скриптов из шаблонов и метаданных. Но естественнее эти подходы работают на языках с динамической типизацией, а на C# вот теперь можно использовать dynamic. Вообще, мне бы ассоциативного массива хватило плюс эвалуации кода из строковой переменной, но многим это покажется не серьезным, не концептуальным :)
Программисты браузеров, при программировании браузеров строят вполне конкретный модели и решают очень конкретные задачи:
1. Рендеринг текста.
2. Общение по HTTP
3. Автозагрузка страниц…

Я это имел ввиду.

Из статьи я понял, что сanvas можно считать метамоделью тогда и только тогда, когда html+js можно считать метаданными. Правильно понимаю?
А html+js — метаданные потому, что декларативный + императивный характер и выполняются в виртуальной машине? Но ведь в виртуальной машине, а не прикладной виртуальной машине…
Уточните пожалуйста разницу между прикладными задачами и системными.
Ну вот с браузером, как с примером, я согласен, есть проблема — это системная задача, а не прикладная. А все средства HTML5 являются и моделью и метамоделью одновременно. Как Вы и сказали, при наличии HTML+JS, да еще + динамических запросов, возвращают JSON — конечно эти компоненты браузера работают как метамодель. Но браузер при этом не становится прикладной виртуальной машиной, а скорее операционной системой, а вот прикладной виртуальной машиной можно считать часть JS скриптов. Это запутанный пример, хоть он и лежит на виду, но я его приводить не люблю.
А как быть с проблемой избыточного функционала? Адаптация такой системы может быть сравнима по затрачиваемым усилиям разработке системы с нуля только под заданные нужды.

На определенном этапе абстрагирования ваша система вырождается из прикладной в систему разработки приложений. Думаю, с этого собственно и стоило начинать.
Это смотря как пользоваться, на практике, нам это позволяет, например, сгенерировать интерфейсы для 100 таблиц за 5 часов или понизить трудоемкость разработки интерактивной анимации в 80 раз (это не не шутка, мы на примере считали по затраченному времени). Наша задача — понизить необходимый уровень специалиста по адаптации с программиста или архитектора, до пользователя или эксперта предметной области. Но конечно, любая идея, доведенная до экстремизма — страшна.
Вот такие примеры, как веб браузеры, (а вместе с ними — СУБД, и другие подобные решения, реализующие метамодели) очень надо включить непосредственно в статью. По опыту, человеку, далекому от понятия метамодели, объяснить что это такое и зачем нужно почти невозможно без живых, понятных ему примеров. В результате получается, что статья реально доступна только тем, кто уже и так понимает что такое метаподход. А для этой аудитории, честно говоря, ничего интересного не прозвучало :-(.
Так браузер не особо хорош, как пример, он понятен сходу, ведь принцип тот же, но когда начинаешь его копать то оказывается, что «сanvas можно считать метамоделью тогда и только тогда, когда html+js можно считать метаданными», как резонно заметил TheHorse. Тут нужно примеры, как пример с учетом ресурсов. Я наберу хороших примеров, это же как-то нужно еще студентам пояснить, а не только инженерам-программистам.
Тогда (из своего опыта) рекомендую включить в примеры задачи управления документами вообще и документооборота в частности (которые в статье почему-то упомянуты как не нуждающиеся в метамодели). Я много лет занимался вопросами как раз обобщенных решений для работы с документами, так что могу с уверенностью утверждать, что описываемый Вами подход в этих задачах вполне применим.
И даже напрашиваются…
Если я правильно понял, то 1С: Предприятие работает по такому же принципу. Если так, то вопрос: в чём принципиально новое именно в вашем подходе?
Я не претендую на создание принципа, он существовал, кстати, и до 1С. Более того, не существует таких программных систем, в которых не применялись бы элементы метапрограммирования. Я лишь применяю к этому принципу научный подход, исследую, осмысляю и описываю. В этом принципиальное отличие науки от техники, которая создает, но не принципы, а их реализации, внедрения. Архимед не создавал закона Архимеда, он его сформулировал, а тела погруженные в жидкость выталкивались и до него.
Тогда, пожалуйста, побольше практических примеров, потому что с точки зрения теории метапрограммирование — это то же самое программирование, только задача чуть покрупнее.
Разработка метамодели для последующего обощения функционала требует гораздо большего времени и анализа, чем собственно реализация бизнес логики. а бизнес, который платит деньги, требует, чтобы было готово «вчера», в лучшем случае — «завтра». Поэтому в своих проектах мне практически не удается выделить и использовать метаданные. Когда приходит понимание, что можно было обобщить и какие метаданные были бы полезны — проект уже закрыт, а впереди новый.

но тема очень интересная, жду продолжения :)
monzdrpower,
вы совершенно верно указали на финансовую составляющую этого подхода. Если клиент клиент готов к спонсированию подобного подхода — он получает и все плюшки. Если вы (или ваша компания) вкладываетесь в построение метамодели для определенного вида задач, то продавать решения на основе этой модели можно гораздо выгоднее (и/или быть более конкурентоспособным, предлагая реализацию быстрее/дешевле чем конкуренты). В этот момент мы подходим к известным понятиям рынка — оценке рисков и выбору области для инвестирования.
На мой взгляд, именно подобные подходы на основе мета-программирования и позволяют решать серьезные бизнес-задачи на разумное «на вчера».
ага, а еще эти методы позволяют аргументировано и безрезультатно проедать бюджет в течение весьма длительного времени. Потому как для того чтобы команда успешно реализовала метамодель, пригодную для практического применения, сначала нужно лет несколько успешно порешать практические задачи на прикладном уровне. А без этого почему-то получается очередной многофункциональный, очень полезный, но неповоротливый комбайн, который никто не понимает как использовать в конкретной задаче. :-(
Пример — Hibernate :-) Сообщество его уже довольно долго пилит, и до сих пор в сложных случаях оно не работает.
Хотя есть и удачные примеры, типа SQL, но это уже полноценный DSL, без хаков.
Есть такая поговорка, что классный бильярдист не делает сложных ударов. Все его удары довольно простые. Но конечно тут есть определенная доля лукавства, потому что, чтобы следующий удар был простой — нужен хороший «выход битка» после предыдущего удара. В этом собственно и заключается сложность бильярда, не в «кладке», а в «выходе» и построении серии.
Так и в программировании — джедаем нужно быть не для того, чтобы «решать сложные случаи», а для того, чтобы предвидеть и избегать их, выбирая простые и эффективные способы решения задач.

Это был псто в защиту Хибернейта :)
Я часто чувствую, что буксую, до тех пор, пока не выделю из модели мета-модель.
Как правило, именно после этого становится очевидным выбор адекватных задаче инструментов, часто уже существующих в виде кода или (если на пути встает юридический отдел) методик.
К каким-то запредельным накладным расходам (в разработке ли, в исполнении ли) это не ведет, если не быть догматиком и вволю экспериментировать на стадии прототипирования («Clean code» и палитра рефакторингов в помощь).
Видимо, у Вас мелкий или средний бизнес.
В крупном бизнесе, как правило, выделяют инвестиции на анализ и обобщение подходов.
Мы делали документооборот для сети гипермаркетов с филиалами по всей стране. Ни на какой анализ время никто не выделял, экономили на всем, велено было сделать на опен-сорс продуктах за полгода, ибо «в апреле начало годовой договорной кампании». Сделали к маю.
Им не нужно открывать исследовательскую лабораторию, им деньги надо зарабатывать.
Это чистый прощелк руководителя или ориентация на быстрый возврат инвестиций. Любые архитектурные подходы дают результат только после нескольких лет применения и внедрения, а научные исследования после 8-10 лет, у нас бизнес для этого очень нетерпелив.
Почему для задач, где количество классов обрабатываемых объектов сравнимо с количеством их экземпляров, необходимо использовать принципиально другой подход?

Сложности на пути повышения абстракции программных компонентов и структур данных, должны быть несколько другими. Комментирую ваши пункты:
1. Связывание по зашитым в программный код идентификаторам — неизбежно, и будет присутствовать и в виртуальной машине и в коде метамоделей.
В этом контексте, сложность модификации кода с целью повышения уровня абстракции, не сложнее любых других модификаций объема того-же порядка.

2. Уже говорил, что динамическая типизация и интроспекция — не обязательны. Обязательным считаю динамическое определения формата, но не типа.

3. Смешивание предметной области и системных задач в одном классе — просто низкокачественный код, и является сложностью для любых модификаций.

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

По той же причине, что и для слабо-структурированных, слабо-формализуемых задач проще использовать бессхемные хранилища (например, MongoDB), чем реляционные СУБД. Представьте, что Вам нужно сделать 10.000 классов при 50.000 экземпляров — это же неподъемная задача, нужно строить такие уровни абстракции, при которых эти же 50.000 экземпляров смогут уложиться в 50 классов. Конечно, я оперирую пока не четкими метриками (одного порядка, много, мало...), но можно найти тут более четки границы, описывающие оптимальное количественное соотношение.
Связывание по зашитым в программный код идентификаторам — неизбежно, и будет присутствовать и в виртуальной машине и в коде метамоделей.

Я не предлагаю избавиться от идентификаторов или избавиться от связывания, но в метамодели будет связывание по идентификаторам не привязанным к предметной области. Например, в задаче с учетом ресурсов, мы будем оперировать понятиями «ресурс», «задача» и «поток обслуживания», а не классами «рабочее время программиста», «разработка компонента информационной системы» и «процесс разработки ПО». Переменные остаются, но будет больше динамических классов или ассоциативных массивов (в зависимости от языка и технологий).
Уже говорил, что динамическая типизация и интроспекция — не обязательны. Обязательным считаю динамическое определения формата, но не типа.

Это уже техники, можно использовать массив, в котором хранить все типы в строковом формате и иметь еще одно поле, по которому определять тип. Но это же, будет по сути ручная реализация интроспекции и динамической типизации. Вот в форматах сериализации и всяческих синтаксических конструкциях так и есть. А в оперативной памяти гораздо быстрее работать с типизированными переменными, чем парсить синтаксисы или хранить для каждой переменной еще и переменную с описанием ее типа, при каждой операции обращаясь к ней.
Смешивание предметной области и системных задач в одном классе — просто низкокачественный код, и является сложностью для любых модификаций.

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

Согласен, но это уже искусство и дар программиста, работающего над метамоделью. Я лишь стараюсь оторвать программиста от рутинного кода и дать ему обзор методов, с помощью которых можно поднять эффективность, повторное использование и гибкость.
Интересно, что я натолкнулся на Хабре на такую статью. Я как раз сейчас интересуюсь такими вопросами, меня постепенно подгоняли мои предыдущие проекты к этому, а теперь ещё MPS в руки попал :)
После прочтения статьи меня интересует вопрос — а какими инструментами вы разрабатываете метамодель и метаданные? Для меня сейчас отсутствие IDE для этого всего является проблемой, так как по сути мы создаем свой язык, и программисту приходится соблюдать его, а не только фактический формат, в котором описаны метаданные.
Это не простой вопрос, и если для разработки метамодели подходят все те же инструменты, что и для статической модели, то вот для метаданных в большинстве случаев, ни какие распространенные IDE не могут быть применены и нужно разрабатывать свою IDE или хоть какой-то простой редактор. Метаданные нуждаются в валидации и отладке, в диагностике ошибок и тут работы много. Но самый смешной и радостный момент у меня был, когда я сделал такой редактор для метаданных универсально редактора баз данных и получил на выходе уже динамически интерпретированный такой же редактор, но гораздо удобнее ) с того времени, часто редактирую метаданные в IDE, созданном на метаданных же.

О языках и технологиях: в разное время мы использовали разные платформы (Clipper, Delphi, C#, PHP, NodeJS) и разные СУБД (dBase, Informix, Interbase, MsSQL, Oracle, MySQL, MongoDB), но подход с динамической интерпретацией реализовывали с вариациями везде. Постепенно понимание развивалось и сейчас меняется. Есть надежды, что окончательно переведя все наработки на JS, мы перестанем быть зависимы от платформы, контролируемой корпорациями (Borland, Microsoft, Oracle, Apple) мы перейдем на зависимость от стандартов (IETF, W3C), это гораздо приятнее. А на JS с его широкими динамическими возможностями мы уже покрыли всю клиентскую и большую большую часть серверной части. И я тут даже не столько о веб-приложениях, как о том, что JS имеет множество реализаций и мы можем встроить интерпретатор JS или даже полноценную виртуальную машину V8 в свой продут на любом языке. А в Windows 8, кстати, JS является одним из основных языков разработки оконных приложений на ряду с C#. В новом маркете Win8, кстати уже есть наше приложение, полностью построенное на динамической интерпретации метамодели (статью про него, кстати еще весной, сразу после публикации в маркете, мы выложили на Хабр, но администрация ее заблокировала, к сожалению).
Ещё один аспект — если не секрет, разработкой и поддержкой метаданных кто занимается? Ваш программист или администратор системы уже на стороне клиента?
Изменение метаданных происходит отдельно от приложения или внутри самого приложения через специальный интерфейс?
В разных приложениях по-разному, есть с отдельным редактором, в который вводит метаданные специалист по предметной области (например юрист, вносит свои экспертные данные), в другой системе аниматор в своем специализированном IDE работает, а в Data-aware приложениях редактор встроенный, иногда сами пользователи вносят изменения в метаданные (они метамодели не меняют, только влияют на ее интерпретацию), могут добавлять поля, изменять типы и даже валидацию менять, выбирать визуальные контролы, устанавливать их поведение, но это все в рамках, ограниченных разработчиками. Систем, в которых метамодель сама разработана на динамическом языке, и происходит двойная динамическая интерпретация мы не еще не реализовывали, но пытаемся в экспериментальном режиме.
Как то все убер-круто выглядит. Не могу поверить, что все так гладко и красиво. И на веб уже перешли, и метаданные с редактором столько очевидны, что их менять кто угодно может (я не про валидацию и визуальщину, а про предметную область), и редактор для всего есть, и работает везде…
Ну проблем еще полно, но выглядит уже внушительно. Сами пользователи конечно правят мало и не все способны, но правят. А вообще, с этим классом систем постепенно выделяется отдельная ката суперпользователей, которые не программисты, но метаданные править могут и в голове предметную область держат. По поводу «на веб уже перешли»: в одном из проектов у нас сейчас к одному серверу подключаются интерфейсы разных языков, андроид-приложение на Java, веб-интерфейс, Windows Phone приложение на C#, и скоро будет iOS приложение на Objective C. Редактор оставляет желать лучшего, от него одна радость, что он сам себя редактирует )))
Я думаю, это следующий шаг в разработке ПО. Программы для клиентов уже есть — их делают программисты. Теперь облегчать труд программистам, и здесь, я думаю, ещё непаханный край)
Святой грааль программирования — это программа, которая делает другие программы по команде оператора.
Динамическая интерпретация — это не искусственный интеллект и не аутопоэтические системы, программа сама себя не пишет, она только строит себя по шаблону. Мы не искореняем интеллектуальный труд инженера, мы искореняем копипаст и рутину.
> мы искореняем копипаст и рутину

Путём абстрагирования. Но в итоге мы хотим автоматизировать разработку ПО настолько, насколько это возможно. Конечно, это не ИИ, это попытка приблизиться к тому, что ИИ мог бы дать нам.
А если метаданные изменились из внешней системы, у вас есть механизм контроля изменений для того, чтобы отобразить их на уже существующих схемах в БД?

Мне кажется, что чем глубже копать в сторону метапрограммирования, тем глубже яма )
Не совсем понятно, что такое «из внешней системы», но при изменении метаданных из редактора, обычно даже перезапускать приложения не нужно, они постепенно по мере обращения берут новые метаданные, сравнивая их версии. Динамически менять структуру в реляционках не практикуем), а вот в бессхемных БД — это удобно.

Ну чем глубже комать, тем яма глубже по определению ) Тут нужно останавливаться и закладывать фундамент где-то, прекращать процесс абстрагирования, иначе можно сделать абстрактную программу под названием «программа», которая делает все что угодно + кофе варит.
После введения двойной интерпретации у вас люди разделятся на две группы — первая будет работать на первом-втором уровнях, вторая — на втором-третьем. Причем доля вторых будет увеличиваться, а первых — уменьшаться.
Аналогичное сейчас происходит в языках программирования — интерпретируемые языки начинают вытеснять компилируемые на бизнес-задачах, а в ассемблер и машинные коды уже никто не лезет, разве что в ассемблер виртуальной машины (но это все равно уже не машинный уровень, не так ли?)
И, естественно — примеров второго уровня метамодели людьми создано не очень много.
И все идут из огромного объема практики в различных условиях.
Ни один архитектор не способен проработать два мета-уровня абстракции.
Абсолютно согласен, это только итерационный процесс, эволюция системы. Поднятие уровня абстракции очень полезно для скорости разработки и переносимости кода (ту же бизнес-логику на js можно перенести из проекта в проект вместе в интерпретатором js, коих есть на выбор), для того, чтобы решение было кратким и описывалось в терминах предметной области. Но вот на производительность это влияет не лучшим образом, поэтому чрезвычайно важно регулярно пересматривать этот слоеный пирог и иногда выбрасывать слои из середины.
На практике, программные платформы, основынные на принципах интерпретации метамодели явлются тяжеловесными и страдают проблемами с производительностью. Исходя из опыта поддержки и расширения подобной системы могу утверждать что затраты на разработку весьма высоки, так как большенство технологий (имел опыт в основном с JEE) не применимы в данном контексте, так как они требуют наличия жестко заданной модели предметной области чаще всего в виде POJO. Как результат JPA, EJB, JAX-RS, JAX-WS, JAXB и т.п. — слабые помошники. Но зато сколько радости при проектированнии таких систем :)
Такая же вата у меня сейчас. Из-за этого и поглядываю на DSL + генераторы. Xtext обошел меня стороной, потому что сижу на идейке, но в MPS вижу очень большой потенциал.
Касательно JPA — можно либо сгенерить POJO и методы с конкретными кейсами из предметки, либо сразу жахнуть JDBC.
К сожалению, пока всё это только не на практике, а в проектах.
Внимание! Добавил в статью важную цитату из Мераба Мамардашвили про философский фундамент идеи. Если интересно, читайте Мераба (а лучше слушайте его знаменитые кассетные записи), у него ссылки на Пруста, на Декарта и на Гераклита. Так что, различие порожденной природы и порождающей, было известно давно и над этим задумывались.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории