LINUX.ORG.RU

Какие бывают преобразования фрагмента кода?

 


1

3

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

Другая крайность - причесываем AST рекурсивно какой нибудь функцией, функция принимает узел AST, и возвращает eго замену. Так можно делать что угодно, но слишком брутально иногда выходит.

Как еще можно извращаться?:-)

★★★★★
Ответ на: комментарий от anonymous

Тебе уже намекнули

Я тебе прямо скажу, что ты балбес http://en.wikipedia.org/wiki/Reflection_(computer_programming)

In computer science, reflection is the ability of a computer program to examine (see type introspection) and modify the structure and behavior (specifically the values, meta-data, properties and functions) of an object at runtime

А теперь, пшёл вон, под лавку.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

За ссылки на педиковикию бьют ссаной тряпкой по хайлу.

Ты, тупица, влез в непонятную тебе тему и начал вякать. Ну и обосрался, как в таких ситуациях всегда бывает. Задача, если ты забыл, pattern matching реализовать через метапрограммирование. Для чего нужна рефлексия во время компиляции. Да, она может быть ровно той же, что работает в рантайме, если это Лисп какой, где рантайм и compile time мало отличаются, но весь кайф ситуации в том, что после того, как все макросы раскрыты и код сгенерен, рефлексия уже не нужна, и в рантайме ее можно отключить. Доходит до дебила, или будешь продолжать тупить?

anonymous
()
Ответ на: комментарий от anonymous

Для чего нужна рефлексия во время компиляции

Ну ну, давай посмотрим...

она может быть ровно той же, что работает в рантайме, если это Лисп какой

Так так, это ты про макросы наверное.

весь кайф ситуации в том, что после того, как все макросы раскрыты и код сгенерен, рефлексия уже не нужна

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

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Анон именно про «рефлексию во время раскрытия макросов» и говорит.

ilammy ★★★
()
Ответ на: комментарий от no-such-file

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

anonymous
()
Ответ на: комментарий от anonymous

Рефлексия во время формирования matcher-ов нужна

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

no-such-file ★★★★★
()
Ответ на: комментарий от nerdogeek

PM в C++ есть. см. partial specialization.

anonymous
()
Ответ на: комментарий от no-such-file

Во время формирования матчеров нет объектов которые можно инспектировать

У тебя динамический кретинизм головного мозга. Есть ТИПЫ, и матчеры делаются для ТИПОВ.

а иерархия классов, структура типов и т.п. компилятору и так доступна

Компилятору? Какому компилятору, баран? Мы макрос пишем. Как макрос запросит у компилятора информацию о типах, кроме как через рефлексию?

Ты гонишь какую-то пургу

Ты абсолютно, непробиваемо некомпетентен. Тебе должно быть очень стыдно быть таким тупым.

anonymous
()
Ответ на: комментарий от anonymous

При чем тут рефлексия, дебил? Обычное метапрограммирование, которое с рефлексией никак не связано и, более того, рефлексии по сути противоположно. Так как рефлексия работает в рантайме, во время компиляции тебе нечего «рефлексировать» - значений еще нет.

anonymous
()
Ответ на: комментарий от anonymous

У тебя динамический кретинизм головного мозга. Есть ТИПЫ, и матчеры делаются для ТИПОВ.

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

anonymous
()
Ответ на: комментарий от anonymous

Мы макрос пишем. Как макрос запросит у компилятора информацию о типах, кроме как через рефлексию?

Спросит у другого макроса. Безо всякой рефлексии.

anonymous
()
Ответ на: комментарий от no-such-file

Ну и что тогда мешает взять, да и унаследоваться от QObject?

Это даст список полей и методов? Нет? Тогда это слишком убого.

Это если самому сделать лень.

конечно, важнее то, что в крестах есть шаблоны. Это с одной стороны усложняет рефлексию в общем виде, а с другой делает её ненужной

Просто ты не понимаешь, что это и зачем нужно.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Ну так чем же он «хуже»?

Тем, что его можно использовать только на внутреннем предствалении программы. Если хочешь сказать, что это не хуже встроенного в язык PM, с тебя пример использования твоего.

tailgunner ★★★★★
()
Ответ на: комментарий от O02eg

Делать можно всё, что можно делать с деревьями, не?

не совсем. Исходное деререво считается априори корректным (т.е. реализует некоторый корректный с т.з. компилятора фрагмент кода). После произвольного преобразования код может стать некорректным.

AIv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

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

От рукожопия тоже надо защищаться, поэтому такой вариант также исключать не стоит.

d_Artagnan ★★
()
Ответ на: комментарий от no-such-file

Т.е. я прав на счет «в 50 раз медленнее»?

Как по мне - так ты не прав. Вообще говоря.
Во-первых, если ты дрочишь только скорость и только на скорость исполнения - специально для таких упорышей можно сделать и быструю рефлексию. Даже логарифмическую, даже константную, вероятно.

Во-вторых, любой неупоротый со всей очевидностью понимает, что любая операция чего-то да стоит. Стоит не только тактов, но и битов памяти. Еще он понимает, что рефлексия дает множество вкуснейших плюшек (см. хотя бы потуги по копированию hibernate / spring на С++), и в выборе между «быть рефлексии, но относительно недешевой» и «не быть ей вообще» выберет первое.

d_Artagnan ★★
()
Последнее исправление: d_Artagnan (всего исправлений: 1)
Ответ на: комментарий от tailgunner

>> Ну и что тогда мешает взять, да и унаследоваться от QObject?
Это даст список полей и методов? Нет? Тогда это слишком убого.

Даст. Список ручками помеченных методов (Q_INVOKABLE) и объявленных пропертей (Q_PROPERTY).

ilammy ★★★
()
Ответ на: комментарий от ilammy

Даст. Список ручками помеченных методов (Q_INVOKABLE) и объявленных пропертей (Q_PROPERTY).

Руками помечать? Ну я и говорю - убого. Ладно, а типы пропертей и типы/сигнатуры методов оно даст, или для метода, принимающего std::vector придется еще и STL пометить?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ладно, а типы пропертей и типы/сигнатуры методов оно даст, или для метода, принимающего std::vector придется еще и STL пометить?

Да, ты правильно понял, что его придётся помечать (через Q_DECLARE_METATYPE). Сигнатуры даст. Строками :) В Qt4 вообще одной строкой, которую ещё парсить надо; в Qt5 немного исправились.

ilammy ★★★
()
Ответ на: комментарий от anonymous

Спросит у другого макроса. Безо всякой рефлексии.

Типы фундаментальны, а не макросами реализованы.

anonymous
()
Ответ на: комментарий от AIv

посмотри xpath/xquery. емнип это тоже контекстно-свободная грамматика

MyTrooName ★★★★★
()
Ответ на: комментарий от anonymous

Типы фундаментальны, а не макросами реализованы.

Ну так реализуй по-человечески, макросами.

anonymous
()
Ответ на: комментарий от AIv

Исходное деререво считается априори корректным (т.е. реализует некоторый корректный с т.з. компилятора фрагмент кода). После произвольного преобразования код может стать некорректным.

Введение типов ветвей и узлов для ограничений, включая переменные?

O02eg ★★★★★
()
Ответ на: комментарий от AIv

В основном образования : -)

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

O02eg ★★★★★
()
Ответ на: комментарий от AIv

я думаю эта тема хорошо раскрыта, надо просто знать где смотреть

В области генетического программирования.

O02eg ★★★★★
()

Допустим есть фрагмент кода в виде какого то объекта (в виде AST) - какие есть возможности для его анализа и преобразования?

Например, стрелки. Единственный вариант, который я пока вижу. Нужно просто-типизированное LC это будет одна конструкция из стрелок/2-стрелок, нужно LC с зависимыми типами - другая, с субструктурными (линейными, в частности) - ещё третья. Т.е. фиксированное подмножество теории категорий само по себе довольно бедная метатеория, просто язык, в котором можно выразить все эти вещи. Мартин-Лёф предлагал формулировать разные теории типов в рамках метатеории LF, вот также это можно делать в рамках метатеории ТК.

Ну, например, берём декартово-замкнутую категорию Set, она же классический топос, т.е. категория всех малых множеств и тотальных функций, в agda она так и называется - «Set». Берём категорию всех малых категорий и функторов Cat (Set1 в agda) и утверждаем:

  • Любой тип который может использоваться (ADTs, GADTs, Inductive families) это объект Set (объект топоса, в общем случае), т.е., как следствие, множество - множество всех термов данного типа.
  • Любой параметрически-полиморфный тип это эндофунктор на Set, т.е. специального вида стрелка в Cat. (Непараметрический тип, который объект в Set, это вырожденный случай функтора из терминальной категории (как-то так)).
  • Любой конструктор типа данных который может быть это стрелка в Set (стрелка в топосе, вообще).
  • Любая функция которая может быть это тоже стрелка в Set, но отдельным классом (чтобы не путать стрелки-конструкторы и стрелки-функции). Как следствие, «функция» - тотальная функция между множествами.
  • Любая композиция стрелок с учётом декартовых произведений и экспоненциалов это любой правильно составленный терм в данной системе (тут типизация из коробки).
  • Любое определение конкретной редукции это 2-стрелка (струнная диаграмма).
  • Любой конкретный ход редукций (вычислений) это композиции 2-стрелок (струнных диаграмм). + Правила построения редукций из коробки.

Например:

-- Тут рисуем коммутативную диаграмму:
ℕ : Set
0 : 1 → ℕ
s : ℕ → ℕ

-- Продолжаем коммутативную диаграмму:
+ : ℕ → (ℕ → ℕ)

-- Рисуем две струнных диаграммы, которые можно сочетать:
e₁(+) : + ∘ a ∘ 0 ⇒ a
e₂(+) : + ∘ a ∘ (s ∘ b) ⇒ s ∘ (+ ∘ a ∘ b)

и это просто ТК (можно представить формальный синтаксис такого языка), безотносительно какого-либо ЯП, но понятно из каких ADT и функции это получилось.

Тут ещё интересно, что можно легко добавлять конструкторы и правила редукций (как если бы в хаскеле можно было дописывать ADT и pattern matching cases по разным модулям).

Сами по себе 2-стрелки это непосредственно струнные диаграммы, т.е., рисуя коммутативные диаграммы, получим схемы типов, рисуя струнные - flow chart.

  • Любая конкретная оптимизация это 3-стрелка. Правила построения оптимизаций тоже из коробки.

Например, если есть линейная рекурсия:

f x = z
f y = g (f (h y))

(f не появляется в g и h), т.е.:

-- любая стрелка вида:
f : x + y → r

-- с 2-стрелками вида:
e₁(f) : f ∘ x ⇒ z
e₂(f) : f ∘ y ⇒ g ∘ f ∘ h ∘ y

то она убирается такой 3-стрелкой:

-- Рисуем диаграмму между струнными:
o(f, f′) : e(f) ≡> e(f′ ∘ z)

-- TCO форма:
e₁(f′) : f′ ∘ a ∘ x ⇒ a
e₂(f′) : f′ ∘ a ∘ y ⇒ f′ ∘ (g ∘ a) ∘ (h ∘ y)

и остаётся только TCO.

Процесс унификации по 3-стрелкам это процесс оптимизаций, а процесс унификации по 2-стрелкам - интерпретации или компиляции (тогда нужен target). Как компилировать в target - конструкторы, например, достаточно точно отражаются в си-подобные структуры и объединения в памяти, можно даже в случае (s : ℕ → ℕ) или (_:_ : a → [a] → [a]) или вообще (con : [no `t' appears] → t → t) пытаться делать не связные списки, а аллоцируемые/реаллоцируемые массивы. Про компиляцию редукций ничего не скажу - только, наверно, тут, в первую очередь, нужен критерий линейности представляемого терма и/или его линеаризация.

anonymous
()
Ответ на: комментарий от anonymous

Я понял отдельные слова))) Во вт попробую обсудить это c бол. продвинутыми товарищами

AIv ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Мне кажется, что «стрелки» из теорката - несколько не то. Тут или преобразования грамматик, или работа с деревьями.

А так я тоже ничего не понял, ОПу не оптимизации надо.

O02eg ★★★★★
()
Ответ на: комментарий от O02eg

А так я тоже ничего не понял, ОПу не оптимизации надо.

Неудивительно, это ведь паста, и к обсуждаемой теме она отношения не имеет.

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от O02eg

Никак к сожалению пока, т.е. все на усмотрение пользователя.

AIv ★★★★★
() автор топика
Ответ на: комментарий от d_Artagnan

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

И где она, никому не нужно что ли?

Еще он понимает, что рефлексия дает множество вкуснейших плюшек

Если речь идет про ORM, то все это изначально костыли, чтобы впихнуть объекты в реляционные БД. Преимущество крестов в том, что можно использовать встроенные объектные базы с прямым отображением обект->запись и доступом просто по указателю. На яве вы так сделать не можете уже потому, что реализация встроенной БД на яве будет заведомо тормознее, чем использование готовой внешней БД. Приходится брать костыли.

(см. хотя бы потуги по копированию hibernate / spring на С++),

Что касается потуг, то их тяжесть связана именно со стремлением обеспечить высокую скорость, а не функциональность. С реализацией функциональности того же hibernate (со скоростью и затратами явы) никаких проблем нет.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Я так полагаю, что о смещениях полей можно не спрашивать

Там немножко другая схема, метасвойства и метаметоды получают по индексу (int). Для метаметода есть методы parameterNames() и parameterTypes() которые возвращают списки строк. Так что ничего парсить не надо, std::vector помечать не надо.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Есть ТИПЫ, и матчеры делаются для ТИПОВ.

Ололо. Ты только что описал шаблоны C++. Я тут уже говорил что шаблоны во многом являются альтернативой рефлекcии (типичный пример - traits), но все таки это не рефлексия, а вариант метапрограммирования.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Я так полагаю, что о смещениях полей можно не спрашивать

Там немножко другая схема, метасвойства и метаметоды получают по индексу (int)

ты правда не понимаешь, о чем речь? Смещение поля. Т.е. смешение поля от начала объекта, в байтах. Какие нах метасвойства, о чем ты вообще?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

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

AIv ★★★★★
() автор топика
Ответ на: комментарий от AIv

Для структуры надо вызвать макрос м перечислением полей

Печально. Я так понимаю, ничем сложным вроде парсинга DWARF вы не заморачивались?

Если тип пользовательский он должен быть описан аналогичным образом.

Шаблоны, разные виды наследования?

tailgunner ★★★★★
()
Ответ на: комментарий от AIv

После произвольного преобразования код может стать некорректным.

Теоретически, можно подобрать типы AST1 и AST2 такими, что они будут описывать ровным счётом корректные деревья (тип дерева и связанный зависимый предикат). Тогда ответ простой — наиболее общие преобразования это ровным счётом функции AST1 -> AST2. Либо AST -> AST, если язык один. Преобразования удовлетворяющие свойствам — функции удовлетворяющие им же. Практически — можно отсеивать вход и/или выход проверками во время выполнения (вместо предиката на уровне системы типов).

quasimoto ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.