Re[42]: Являются ли макросы свидетельством недостаточной выр
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 09.08.07 10:33
Оценка:
Здравствуйте, cl-user, Вы писали:

CU>1. "ниасилил"?


В следующий раз будет бан.
... << RSDN@Home 1.2.0 alpha rev. 688>>
AVK Blog
Re[47]: Являются ли макросы свидетельством недостаточной выр
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 09.08.07 10:33
Оценка: 3 (1)
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>А какого типа List? (В примере будет Customer, как я понимаю, но меня интересует "вообще"). Там же не Object, который разгребается рефлексией?


Именно что object.
... << RSDN@Home 1.2.0 alpha rev. 688>>
AVK Blog
Re[12]: Являются ли макросы свидетельством недостаточной выр
От: cl-user  
Дата: 09.08.07 10:37
Оценка:
Здравствуйте, mkizub, Вы писали:

M>- Скорость работы специализированной железяки определяется в первую очередь этой железячностью.

M>- Никому, как правило, нафиг не нужно исполнять программы общего назначения на специализированной железяке, и писать под неё компилятор для С — нафиг не нужно, а нередко и просто невозможно.
M>- Компилятор на С врядли обеспечит значительный прирост скорости, поскольку специализированные вещи делаются на ассемблере, а связка между функциями занимает 5% времени исполнения, оптимизировать эти 5% такой ценой — безумие.
M>- Несмотря на всю низкоуровневость С или аналогичных языков — у них есть неприятное свойство в виде наличия call conventions, которые сильно затрудняют их работу с ассемблерными методами.

M>Учитывая всё это (а может что-то и позабыл) — реализация кода на Форте в 99% случаев (т.е. кроме крайне массовых продуктов, вроде специлизированного GPU) будет быстрее, дешевле, надёжней, мощнее. Мизерные потери на скорость на этом фоне никого не волнуют. Я тебе больше скажу — на 9 телефонах из 10 (с ARM CPU), с которыми я работал — код компилируется в Thumb режиме. Да, это медленее на 30%, но на эти же 30% сокращает размер кода — и производители выбирают размер, и это не для специализированной железяки, а для девайса общего назначения.


Я уже писал — ничего не имею против форта как языка для "ембедщины" и т.п.
Re[45]: Являются ли макросы свидетельством недостаточной выр
От: cl-user  
Дата: 09.08.07 10:45
Оценка:
Здравствуйте, mkizub, Вы писали:

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


CU>>Что есть ЯВУ в мета-программировании? (N не вспоминать )


M>Что есть ЯВУ вообще? Удобный синтаксис (отображение, восприятие кода),


субъективно

M> программирование в более высокоуровневых абстрациях (врочем, этого к Лиспу тяжело добавить больше, чем у него уже есть)


угу

M> и оптимизация опираясь на эти абстракции, а так-же переносимость (вот этого у Лиспа не очень).


С чем "не очень"? С переносимостью между чем и чем?

M> Есть ещё несколько полезных средств разработки, ассоциированных с ЯВУ (вроде IDE), которые менее удобны для "ассемблеров" в виду отсутствия у них конструкций со сложной семантикой. У Лиспа семантика расширяемая, но нет средств "сообщить/описать" эти расширения в IDE, поэтому последний так-же слабо поможет в написании мета-программ.


Не понял... SLIME прекрасно подсказывает количество и характер (для некоторых реализаций — и имена параметров) при вызове функций/макр. Типов — да, о них ничего не говорит. Но мог-бы (для тех реализаций, которые поддерживают эту "метаинформацию").

M> Или в декларацию новых семантических конструкций необходимо добавлять описание для их понимания IDE — что-то вроде мета-протокола, как CLOS описывает ОО, так и какой-нибудь CLIDE будет описывать интеграцию с IDE.


SLIME использует средства инспектирования каждой отдельной реализации.

M>Вот тут статья, которую всё никак не собирутся опубликовать на RSDN.

M>http://www.symade.org/SOP_and_SymADE.doc
M>Я пишу новую и побольше, но это ещё не один день займёт.

Ок, почитаем.

Так, это, более ВУ Я нет?
Re[9]: Являются ли макросы свидетельством недостаточной выра
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 11:10
Оценка: 6 (1) +1
Здравствуйте, VladD2, Вы писали:

L>>Разумеется, gmap проходит по всем узлам, поэтому он медленный. Для ускорения можно и исключить ветки из просмотра (правда, чисто это будет, насколько я знаю, только для определённых случаев — для этого варианта не делаем, а для этого делаем), можно решить и циклы. У тебя разве по другому?


VD>У меня универсальный механизм компайл-тайм рефлексии и средсва прмого генерирования кода. С их помощью создание частных, всокопопроизводительных случаев дело времени и техники.


Не понял в чём отличие от моего случая.

L>>Э-э-э... А зачем Хаскелю интеграция с VS?

VD>А зачем вообще сам Хаскель? Вопрос из той же серии.

Да нет, я не о том. Я согласен, что IDE — это совсем неплохо. Я имею в виду зачем именно VS?
Есть же Emacs, vim, есть собственные IDE — hIDE например или yi.

У меня в Emacs есть автодополнение, навигация по коду, подсказки по типам функций например, список для быстрого нахождения нужной функции/класса/инстанса, рефакторинг, запуск в GHCi. Сам же редактор очень даже неплохой.

VD>ОК. То есть мы ведем речь по сути о полиморфном решении проблемы и пользуемся тем фактом, что полиморфизм в Хаскеле определяется классами типами которые являются эдакими аналогами внешних интерфейсов Явы.


Да.

VD>Сразу пояляется две вароса.

VD>1. Это только мне кажется все слишком запутанным, а всем мало-мальски знакомым с Хаскелем все очевидно? Например, я так и не понял как этот волшебный deriving объясняет компилятору как отображать поля некой записи (или как там составные типы в Хаскеле обзывают?). Что при этом происходит со встроенными типами вроде кортежа? В общем, откровенно говоря я так и не вкурил тонкостей. Мне все это кажется магией (т.е. содержит много необъясненных моментов).

В GHC деривинг для Data, Typeable встроен. Но его можно описать: это решение называлось раньше (как сейчас не вспомню, если интересно, потом поищу) — derivable type classes, когда мы описываем класс сразу с шаблоном реализацией, т.е. по сути это специализированные макросы, как и в случае с rewrite rules.

VD>2. Что делать если в каких-то частных случаях нужно сделать частный алгоритм обхода? Ну, как с тем же зацикливаением бороться?


Никак не надо с ним бороться. Из-за ленивости языка то, что не надо — не вычислиться.
Пример другого частного алгоритма обхода приведи, а то я не очень понимаю.

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


В SYB в принципе неважно пользуешься ли ты автоматической генерацией экземпляров классов или пишешь их вручную. Идея не в этом. Писать там мало, но пользовать gmap можно везде. Автоматическая генерация — это следующая задача по сокращению кода, и она уже лучше всего (IMHO, как и всякая задача по генерации кода) решается макросами или специальными средствами, подобными макросам.

VD>У этого подхода есть как приемущества так и недостатки. Приемущетсва: гибкость, наивысшая скорость получаемого кода, прямолянейность реализации. Недостатки... пожалуй он один, но глобальный — это компайлатайм-решение. И оно не может применяться для типов о которых неизвестно во время компиляции (например, о типах из динамически подключаемых библиотек).


Почему? макросы же могут и в рантайме работать.

VD>Можно об этом по продробнее? И особенно о том как можно совместить генерируемые компилятором сущности (ну, там Typeable и т.п.) с custom-кодом который нужен прикладному программисту.


То, что в других языках делается рефлексией, в Хаскеле просто является экземпляром класса Typeable:

data Person = MkPerson { personName :: String, personAge :: Int }

instance Typeable Person where
    typeOf _ = mkTyConApp (mkTyCon "Main.Person") []
        
instance Data Person where
        toConstr person =
                mkDataConstr (dataTypeOf person) "MkPerson" Prefix
        dataTypeOf person = ... -- неохота писать, смысл ясен полагаю.


То же самое сгенерится в случае если мы укажем deriving (Typeable, Data).
Затем мы может получать информацию о типе, которую сами же и забили.

VD>Ну, скажем простейшая задача. Хочу сгенерировать некий код для Х типов меня в нем код функции в зависимости от тех или иных условий. Ну, скажем если в типе есть строки, то вывести их на консоль, а если нет, то ничего не делать.


Это тот же gmap , только не gmapT, тип которого (forall b. b -> b) -> a -> a, а gmapQ :: (forall b. b -> r) -> a -> [r], т.е. мы не отображаем одну структуру в точно такую же, но с изменёнными полями, а делаем по ней запрос для отдельных полей и собираем результаты этих запросов в список. deniok уже привёл пример с подробностями.

Могу лишь добавить, что этих gmap-ов три штуки. Два уже ты знаешь. Третий угадаешь, если вспомнишь на каком языке мы пишем Разумеется, он называется gmapM и относится к монадам. Т.е. это тот же gmapQ, только результат не список, а монада: gmapM :: (forall b. b -> m b) -> a -> m a

На самом деле есть более универсальный комбинатор, через который выражаются все эти три gmap-а, и называется он, разумеется gfold

VD>Ктр такрй SYB?


Scrap Your Boilerplate. Решения, о которых мы говорим.

VD>Может быть, может быть... Но хотелось бы глянуть на реальном тесте. Да и объяснения "природы" более подробнрые не помешали бы.


Ну, я постарался тебе дать самую общую схему, поэтому не могу понять, что именно не ясно?

VD>Хм... Одно "но". Не выполняем (это уже динамическая рефлексия), а генерируем. Чувствуещь разницу? Выполнение по условию в рантайме это немного не то. И гибкость не та, и скрость фиговая.


Да. В SYB для каждого поля делается проверка cast-ом. У тебя сразу выбираются нужные поля.
Насчёт производительности сейчас ничего не скажу, но когда авторы меряли ручное решение и через gmap (с самописным тормозным cast-ом!!) — у них было отставание в 3,5 раза.
Сейчас и cast встроен и он гораздо быстрее, да и оптимизации, которые они для GHC обещали тогда (1999?) наверняка были написаны. Это, конечно, не оправдание, ручное (либо сгенерированное) скорее всего будет быстрее — там всё таки сразу выбираются нужные поля, но вполне возможно, что сейчас разница уже практически незаметна.

VD>1. Когда производится анализ содержимого типа? В рантайме или в компайлатайме? Т.е. генерируется ли компилятором код вроде:

В рантайме

VD>2. Как можно вмешаться "руками"?

Есть комбинаторы, например, everywhereBut. Задачу надо смотреть.

VD>Дык, а эта тема о чем тогда?

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

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

Т.е. "если в языке есть встроенные и при этом достаточно выразительные средтсва решающие задачу без "но", то лучше использовать их", а если используются макросы, то это использование является показателем отсутствия подобных средств. Примерно так.

L>>Эх! Если бы это всегда было возможно. Как на макросах в Хаскеле тот же cast сделаешь (быстрый)? Никак, базовых средств недостаточно.


VD>Значит такие макросы.


Ну представь, что у тебя нет getClass, typeof или как определение типа называется в Немерле. Как ты напишешь быстрый каст, который просто будет сравнивать два указателя?
Хотя это мы отвлекаемся.

VD>Руби, Питон и ЯваСкрипт — это скрипыт. Скрпты до мозга костей. Их методы метапрограммирования на прочь убивают любые потуги в лпане повышения производительности (компиляции), надежности (статические проверки) и поддерживаемости.


Это другой разговор. Раз кто-то ими пользуется, значит кого-то устраивает производительности и надёжность, обеспечиваемые этими языками. Речь не об этом, а о выразительности в построении DSL.

VD>Хаскель все же является типичным представителем статически типизированных, компилируемых языков. И в этом плане его подходы к метапрограммированию интересно сравнить с макросами.


Не знаю, я бы не назвал его типичным. На нём же можно писать без аннотаций типов.

VD>На счет просты — вопрос спорный. Я вот так и не понял мноих аспектов реализации. Хотя похоже на счет gmap я ошибся. Но что-то мне кажется, что в описанинии gmap приведенном тут содержатся "чудесные" средства. То есть нечто, что нельзя сделать если ты не создатель компиляора. Макрсоы же это четко детерминированные средства развития компилятора. Минимальный АПИ который позволяет создавать "чудесные вещи" вроде gmap. Причем, что немаловажно, позволяют любому смертному.


Да нет там ничего Просто визитор.

VD>>>Я не очень понял что значит "управляющие стурктуры". Посему не могу об этом рассуждать. С точки зрения манипуляции функциями Хаскель мало чем отличается от Немерле.


L>>Да и вообще все языки Тьюринг-полные


VD>Лучше бы объяснил термин.


Управляющие структуры? if, for, while, repeat. Ветвление и цикл.
Наверное имелось в виду, что if, while и прочее — легко нарисовать в виду функций, в силу ленивости.


Большое письмо получилось, может разбить?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[28]: Являются ли макросы свидетельством недостаточной выр
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 11:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Как я понял в случае с Парсеком мы просто получим некорректный парсер. Так?


Да.
Но хочу заметить, что это не ограничение того, что не используются макросы. Просто это решение конкретной библиотеки. То же самое решение можно построить на комбинаторах. Делаем для них возможность instance Eq, а потом для <|> просто сравниваем начало левого и правого комбинатора. Если равны — выводим соответствующую ошибку. Будет работать в компайлтайме.

VD>Она мне нитересна, конечно. Но это только один вопрос. А их несколько. Вот в начале этого собщения мы говорим о логике постраителя парсера. Это мне тоже очень интересно. Потом интересна отладка. Да и просто поглядеть на то во что выльется грамматика интересно.


Отладка — в смысле пошаговый дебаггер?

VD>А то абстрано у всех все здорово и красиво. А вот на прктике что-то проблемы вылезают.


Не, я не абстрактно говорю, редко, но применяю Parsec на практике. Конечно, у меня задачи по разбору не такие критичные к производительности, как у тебя, поэтому мне хватает даже простого [Char]. Но это только то, что касается производительности. Что касается описания грамматики, то парсек для меня удобнее чистого EBNF — из-за возможности дополнять своими комбинаторами.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[46]: Являются ли макросы свидетельством недостаточной выр
От: mkizub Литва http://symade.tigris.org
Дата: 09.08.07 11:15
Оценка:
Здравствуйте, cl-user, Вы писали:

CU>>>Что есть ЯВУ в мета-программировании? (N не вспоминать )


M>>Что есть ЯВУ вообще? Удобный синтаксис (отображение, восприятие кода),


CU>субъективно


Безусловно. Плюс — привычка. Исследования показывают, что человек читает буквенный текст (слова) так-же, как иероглифы — как целое. Высокоуровневые конструкции языка человек тоже воспринимает целиком, а не разбивает их на кусочки — конечно, после определённой практики. Степень автоматизма доходит до того, что даже индентация/пробелы влияют на распознавания "образа" и читаемость кода, не говоря уже о различиях С и Паскаль-подобного синтаксиса, и уж тем более синтаксиса Лиспа и Форта.

Кроме субъективности есть ещё и объективные показатели. Например, история развития математики показывает, что она сделала гигантский скачёк в развитии именно за счёт изобретения буквенно-операторной записи математических формул и соотношений. Без этого — сложная математика была просто невозможна, а вершиной её достижений было решение квадратных уравнений. К объективным показателям читаемости Лиспа можно отнести и массовость "ниасиливших". Безусловно, есть те, кому синтаксис Лиспа подошёл, но на порядок больше тех, кому он не подошёл.

Далее. Возможность отображать дерево не целиком, а многоуровнево, скрывая несущественные детали — это объективный показатель. В качестве примера можно привести бесконечные пальцы веером у ФП программистов по поводу выводимости типов. А фактически вся эта выводимость сводится к тому, что часть кода не нужно писать/отображать. Очень небольшую часть кода — всего лишь типы. На фоне возможности, скажем, визуальных редакторов GUI, которые показывают как будет выглядеть диалог, скрывая детали вроде обработчиков событий и настроек layout manager-а — возможности сокрытия ненужной информации при выводе типов — это детский лепет.

M>> и оптимизация опираясь на эти абстракции, а так-же переносимость (вот этого у Лиспа не очень).


CU>С чем "не очень"? С переносимостью между чем и чем?


Лисп задаёт не только новую семантику узлов дерева, но и её реализацию. Она у него неотрывно привязана к декларации макроса. Соотвественно и трансформация дерева макросом предполагается только одна. А если отделить декларацию семантики от транформации, то можно преобразовывать одну абстракцию в разные реализации для разных платформ, или разные реализации в зависимости от настроек компилятора и проекта. Это даст как большую модульность, так и большую переносимость кода.

M>> Есть ещё несколько полезных средств разработки, ассоциированных с ЯВУ (вроде IDE), которые менее удобны для "ассемблеров" в виду отсутствия у них конструкций со сложной семантикой. У Лиспа семантика расширяемая, но нет средств "сообщить/описать" эти расширения в IDE, поэтому последний так-же слабо поможет в написании мета-программ.


CU>Не понял... SLIME прекрасно подсказывает количество и характер (для некоторых реализаций — и имена параметров) при вызове функций/макр. Типов — да, о них ничего не говорит. Но мог-бы (для тех реализаций, которые поддерживают эту "метаинформацию").


Людей мало интересуют имена параметров — это детали внутренней реализации. Людей больше заботит семантика и удобство отображения. Скажем, как это сделано для автоматической генерации кода в IDE — набираем слово for жмём Ctrl-Enter и нам генерят и показывают код

for ( <init> ; <check> ; <iterate> ) <statement>


После чего <поля> заполняются как поля ввода, а не редактирование текста. При этом внутренняя реализация узла для for loop может иметь много других полей, являющихся деталью реализации — скажем, labels для break и continue и т.п., не говоря уже о именах слотов для хранения под-узлов, которые совсем не обязаны быть init, check, iterate.

M>> Или в декларацию новых семантических конструкций необходимо добавлять описание для их понимания IDE — что-то вроде мета-протокола, как CLOS описывает ОО, так и какой-нибудь CLIDE будет описывать интеграцию с IDE.


CU>SLIME использует средства инспектирования каждой отдельной реализации.


А он есть для Eclipse? А то я Emacs не осилил, в силу особенностей реализации своего мозга, который принципиально больше 5 шорткатов запоминать отказывается.

M>>http://www.symade.org/SOP_and_SymADE.doc


CU>Так, это, более ВУ Я нет?


Это вообще не язык. Это концепция (парадигма) программирования (с упором на мета-программирование) и его реализация.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[17]: Являются ли макросы свидетельством недостаточной выр
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 11:20
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это главная фича. "Кода в скобках" попросту нет! На выходе мы получаем список/поток вариантов описывающих грамматические конструкции. Ну, а далее мы прсото анализируем их средствами паттерн-матчинга. В итоге получаем полное отделение описания грамматики от действий предпринимаемых при распозновании тех или иных конструкций.


Понял. Из лексера генерится декларация вариантов, потом их можно разбирать как угодно. То, что генерируется автоматически — это плюс. Насчёт минусов ничего не скажу. У меня, например, зато количество вариантов только то, которое необходимо, а не равное количеству токенов (или правил разбора). Плохо это или хорошо? Наверное, зависит от ситуации. Вот в JSON нужны все варианты — там нужно именно дерево данных, а в разборе выражений — лучше его схлопнуть в какую нибудь свою структуру, причём во время разбора, чтобы не плодить деревья и варианты.

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


konsoletyper говорил, что свои комбинаторы нельзя писать. только те, что есть в EBNF — *, | и т.д.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[17]: Являются ли макросы свидетельством недостаточной выр
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 11:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>К сожалению, нет. Но готов поставить если будут четки инструкции "чего и скока?". За одно многие другие смогут приобщиться.


К сожалению, побился indent, а как тут файл залить можно?

Поставить можно GHC:

http://haskell.org/ghc/download.html

Качаешь, ставишь. Настраиваешь пути

Можно запускать сразу в режиме интерпретации

> runhaskell JSON.lhs test.js


Или сначала скомпилировать, а потом запустить

> ghc --make -O2 JSON.lhs

> JSON.exe test.js

VD>А можно увидить все это в целом? Ну, чтобы с оригиналом сравнить?


Э-э-э.. Что то я туплю с утра. Что увидеть?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[47]: Являются ли макросы свидетельством недостаточной выр
От: cl-user  
Дата: 09.08.07 11:48
Оценка: +1
Здравствуйте, mkizub, Вы писали:

M>>>Что есть ЯВУ вообще? Удобный синтаксис (отображение, восприятие кода),


CU>>субъективно


M>Безусловно. Плюс — привычка. Исследования показывают, что человек читает буквенный текст (слова) так-же, как иероглифы — как целое. Высокоуровневые конструкции языка человек тоже воспринимает целиком, а не разбивает их на кусочки — конечно, после определённой практики. Степень автоматизма доходит до того, что даже индентация/пробелы влияют на распознавания "образа" и читаемость кода, не говоря уже о различиях С и Паскаль-подобного синтаксиса, и уж тем более синтаксиса Лиспа и Форта.


Это к тому, что для перехода на лисп множеству "гуру" придётся переучиваться? Так лисп здесь ни при чём — это с любыми новшествами так. Причём (следуя из текста про математиков) — определённым новшествам обучаться "обязательно", иначе "иди с метлой".

M>Кроме субъективности есть ещё и объективные показатели. Например, история развития математики показывает, что она сделала гигантский скачёк в развитии именно за счёт изобретения буквенно-операторной записи математических формул и соотношений. Без этого — сложная математика была просто невозможна, а вершиной её достижений было решение квадратных уравнений. К объективным показателям читаемости Лиспа можно отнести и массовость "ниасиливших". Безусловно, есть те, кому синтаксис Лиспа подошёл, но на порядок больше тех, кому он не подошёл.


Статистика — ложь. Есть сведения, скольким студентам MIT, в которых пихали схему и которые до этого не знали других языков, списочный синтаксис "не подошёл" (именно _не подошёл_, а не "в следствии объективных причин вынуждены были использовать другие языки")?

А то мы говорим о том, что в средние века большинство населения в Европе умывалось чуть ли не раз в месяц а то и реже — гигиену гнать!

M>Далее. Возможность отображать дерево не целиком, а многоуровнево, скрывая несущественные детали — это объективный показатель. В качестве примера можно привести бесконечные пальцы веером у ФП программистов по поводу выводимости типов. А фактически вся эта выводимость сводится к тому, что часть кода не нужно писать/отображать. Очень небольшую часть кода — всего лишь типы. На фоне возможности, скажем, визуальных редакторов GUI, которые показывают как будет выглядеть диалог, скрывая детали вроде обработчиков событий и настроек layout manager-а — возможности сокрытия ненужной информации при выводе типов — это детский лепет.


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

M>Лисп задаёт не только новую семантику узлов дерева, но и её реализацию. Она у него неотрывно привязана к декларации макроса. Соотвественно и трансформация дерева макросом предполагается только одна. А если отделить декларацию семантики от транформации, то можно преобразовывать одну абстракцию в разные реализации для разных платформ, или разные реализации в зависимости от настроек компилятора и проекта. Это даст как большую модульность, так и большую переносимость кода.


Лисп задаёт _только_ списочный (древообразный) "вид" кода — больше ничего. У вас есть почти полностью управляемый reader и есть возможность вообще вставить свой — какие здесь могут быть ограничения?

И что значит "одна трансформация дерева"? Как можно модифицировать дерево (таким образом, как лисп не может)? Или вы про свой SymADE и про "переносимость AST-а между разными языками"? Так может лучше про ИИ?

M>Людей мало интересуют имена параметров — это детали внутренней реализации. Людей больше заботит семантика и удобство отображения. Скажем, как это сделано для автоматической генерации кода в IDE — набираем слово for жмём Ctrl-Enter и нам генерят и показывают код


M>
M>for ( <init> ; <check> ; <iterate> ) <statement>
M>


M>После чего <поля> заполняются как поля ввода, а не редактирование текста. При этом внутренняя реализация узла для for loop может иметь много других полей, являющихся деталью реализации — скажем, labels для break и continue и т.п., не говоря уже о именах слотов для хранения под-узлов, которые совсем не обязаны быть init, check, iterate.


Писать код "формочками" — увольте

CU>>SLIME использует средства инспектирования каждой отдельной реализации.


M>А он есть для Eclipse?


нет, но для Eclipse вроде есть что-то для лиспа, правда я этого зверя не видел.

CU>>Так, это, более ВУ Я нет?


M>Это вообще не язык. Это концепция (парадигма) программирования (с упором на мета-программирование) и его реализация.


Это пока ещё только концепция и ничего больше.

Так и запишем: "Лисп — ассемблер в МП. Но С ещё не придумали..."
Re[14]: Являются ли макросы свидетельством недостаточной выр
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 13:16
Оценка: 84 (3)
Здравствуйте, VladD2, Вы писали:

G>>Приведи мне пример паттерна, который будет строиться на базе ФВП и паттернматчинга, и покажи, как ты его макросом обернешь.


VD>Возможно неплохим примером будет оператор foreach из Nemerle. О его возможностях можно прочесть тут
Автор(ы): Чистяков Влад (VladD2)
Дата: 03.03.2007
Язык программирования Nemerle заинтересовал многих в первую очередь своей мощнейшей подсистемой мак-росов. Однако и без них Nemerle предоставляет ряд су-щественных улучшений по сравнению с традиционными, императивными языками программирования (такими как Java, C# и C++).
Nemerle, кроме традиционного императивного програм-мирования, поддерживает функциональное программи-рование. Это выражается в наличии конструкций, упро-щающих манипуляцию функциями, построение и анализ сложных структур данных и т.п.
К сожалению, если вы не использовали возможности, присущие функциональным языкам ранее, то вам будет трудно оценить, насколько Nemerle может оказаться вам полезным в реальной повседневной работе. Данная статья призвана в неформальной форме продемонс-трировать это.
.


Мне кажется именно это решение возможно на чистых ФВП и ПМ:

Предствим фильтра как набор комбинаторов, тогда foreach :: (a -> Bool) -> [a] -> (a -> m r) -> m [r]
Т.е. foreach принимает набор комбинаторов, по ним фильтрует входной поток и применяет к отфильтрованным значениям функцию. m здесь тип, имеющий экземпляр Monad (чтобы использовать WriteLine).

Примерная реализация:

foreach pred xs f = mapM f (filter pred xs)


Пусть есть комбинатор is :: a -> Type -> Bool, isPubluc :: a -> Bool и т.д.

1. Вы можете отфильтровать нужные элементы по типу. Например, предположим, что вам требуется из общего списка членов (typeMembers) некоторого типа отфильтровать только те элементы, которые реализуют интерфейс IMethod (то есть являются методами). Это можно сделать следующим образом:


foreach (method is IMethod in typeMembers)
  processMethod(method);


foreach (`is` IMethod) typeMembers processMethod


2. Вы можете использовать защиту, чтобы обработать только нужные элементы. Например, вот так можно исключить из обработки элементы, значения которых равны null:


foreach (elem when elem != null in someList)
  process (elem);


foreach (!= null) someList process


Другой пример – вы можете захотеть обработать только публичные методы:


foreach (method is IMethod when method.IsPublic in typeMembers)
  processMethod(method);


foreach (\method -> method `is` IMethod && isPublic method) typeMembers processMethod


Тут кстати можно описать комбинатор для объединения двух условий, и пусть он тоже называется when:

when :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
when f g x = f x && g x


Тогда

foreach ((`is` IMethod) `when` isPublic) typeMembers processMethod


3. Вы можете указывать один образец варианта. При этом будут отфильтрованы только те элементы, которые соответствуют этому образцу:


def expressions = [Literal(1.23), Mul(Literal(2), Literal(3))];
foreach (Mul(_, _) as mul in expressions)
  WriteLine(mul);


Тут сложнее, в том смысле, что мы должны создать функцию для определения Mul это или нет. Как лямбду или с именем — неважно, но должны. Если выразить foreach через list comprehension, то такой необходимости не будет:

expressions = [Literal 1.23, Mul (Literal 2, Literal 3)]
forM [ mul | mul@Mul{} <- expressions ] print


Если же мы пишем универсальный комбинатор, то должны выразить предикат, определяющий Mul-ность терма.

expressions = [Literal 1.23, Mul (Literal 2, Literal 3)]

foreach isMul expressions print
        where
                isMul Mul{} = True
                isMul _     = False


3. (кстати, почему опять три?!) Вы можете производить декомпозицию вариантов и кортежей непосредственно при объявлении элемента в foreach:


def expressions = [Literal(1.23), Mul(Literal(2), Literal(3))];
foreach (Mul(e1, e2) as mul in expressions)
  WriteLine($"$(mul.Eval()) = $e1 * $e2");


Аналогично (строку не буду собирать)

expressions = [Literal 1.23, Mul (Literal 2, Literal 3)]

-- решение на LH
forM [ mul | mul@(Mul e1 e2) <- expressions ] print (e1*e2)

-- решение на универсальном комбинаторе
foreach isMul expressions (\(Mul e1 e2) -> print (e1 * e2))
        where
                isMul Mul{} = True
                isMul _     = False


4. Самый сложный случай практически аналогичен анонимному применению match в функциях:


def expressions = [Literal(1.23), Mul(Literal(2), Literal(3))];

foreach (expr in expressions)
{
  | Mul(e1, e2) => WriteLine($"$(expr.Eval()) = $e1 * $e2");
  | Div(e1, e2) => WriteLine($"$(expr.Eval()) = $e1 * $e2");
  ...
}


expressions = [Literal 1.23, Mul (Literal 2, Literal 3)]

-- пусть будет ещё один комбинатор - предикат, всегда возвращающий True
ok = const True

foreach ok expressions $ \expr ->
        case expr of
                Mul e1 e2 -> ...
                Div e1 e2 -> ...
                
-- разумеется всё что после $ можно вынести в отдельную (вложенную) функцию, чтобы избавиться от case и expr.


Мне кажется макросы нужны когда нужно нагенерить кучу кода, здесь же обычная "управляющая структура"
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[22]: Являются ли макросы свидетельством недостаточной выр
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.08.07 13:16
Оценка:
Здравствуйте, VladD2, Вы писали:

BZ>>не хаскелю, а байтовым строкам. интересно, ты вообще хоть что-нибудь читаешь из всех ссылок, что тебе приводят?


VD>А что встренные строки Хаскеля поддерживают Юникод?


Вообще должны, но поддерживаются не везде, насколько я знаю. GHC, например, поддерживает, но при выводе в stdout обрезает символ до последних 8 бит

Разумеется, есть решения, но я никогда этим не интересовался.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[48]: Являются ли макросы свидетельством недостаточной выр
От: mkizub Литва http://symade.tigris.org
Дата: 09.08.07 15:07
Оценка:
Здравствуйте, cl-user, Вы писали:

M>>Это вообще не язык. Это концепция (парадигма) программирования (с упором на мета-программирование) и его реализация.


CU>Это пока ещё только концепция и ничего больше.

CU>Так и запишем: "Лисп — ассемблер в МП. Но С ещё не придумали..."

По первых — реализация, пусть и в стадии prrof-of-concept.
Во вторых — уже придумали.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[11]: Являются ли макросы свидетельством недостаточной выр
От: FR  
Дата: 09.08.07 15:57
Оценка:
Здравствуйте, cl-user, Вы писали:

CU>"Памяти мало, на скорость положить" — слишком узкий спектр задач. Даже в мобилку не пойдёт. Вот и остаётся только что засовывать в медленные но хитрые контроллеры да в бутромы всякие — скорость загрузки не критична.


По сравнению с той же явой которую суют сейчас в мобилки форт будет очень шустрым, он медленен только относительно достаточно хорошего си компилятора.
Re[12]: Являются ли макросы свидетельством недостаточной выр
От: mkizub Литва http://symade.tigris.org
Дата: 09.08.07 16:52
Оценка:
Здравствуйте, FR, Вы писали:

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


Не будет. Совать форт, написанный непонятно кем, в свой телефон нормальный человек не будет. Потому как фортовских программ с встроенным вирусом образуется больше, чем сейчас спама образовалось из e-mail-а.
Явовский код — это такой же стек, как и фортовский, плюс проверки на нулевой указатель, выход за границы массивов, проверки типов и прочее. Явовскому интерпретатору просто не от чего быть медленее, кроме проверок — а без них левый код на мобилку не загрузишь.
Больше того, нынешние мобилки прекрасно позволяют компилировать яву в нэйтивный код, памяти у них хватает. И для распространённых на мобилках CPU эти компиляторы написаны и работают. Интепретатор форта не сдюжит против компилятора в нэйтивный код никаким местом.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[27]: Являются ли макросы свидетельством недостаточной выр
От: Andrei F.  
Дата: 10.08.07 03:16
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В Java для этого полно инструментов, в .NET знаю только: http://rail.dei.uc.pt/project_overview.htm


http://rsdn.ru/Forum/message/2564849.1.aspx
Автор: AndreiF
Дата: 29.06.07

еще можно использовать profiler API, чтобы модифицировать IL код перед выполнением JIT-a
Re[13]: Являются ли макросы свидетельством недостаточной выр
От: FR  
Дата: 10.08.07 03:16
Оценка:
Здравствуйте, mkizub, Вы писали:

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


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


M>Не будет. Совать форт, написанный непонятно кем, в свой телефон нормальный человек не будет. Потому как фортовских программ с встроенным вирусом образуется больше, чем сейчас спама образовалось из e-mail-а.


Не будет не из-за этого, а из-за того что место давно занято.

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

M>Больше того, нынешние мобилки прекрасно позволяют компилировать яву в нэйтивный код, памяти у них хватает. И для распространённых на мобилках CPU эти компиляторы написаны и работают. Интепретатор форта не сдюжит против компилятора в нэйтивный код никаким местом.

Угу то-то эта ява так страшно тормозит.
"Интерпретор" у форта как ты наверно знаешь, имеет некторые особенности которые позволяют ему по скорости мало уступать тупым плохо оптимизирующим компиляторам (а явовские в мобилках именно такие), правда эти же особенности мешают построить хороший оптимизирующий компилятор. Но компиляторы у форта есть и посоревноватся с той же явой вполне могут.
Re[49]: Являются ли макросы свидетельством недостаточной выр
От: cl-user  
Дата: 10.08.07 07:02
Оценка:
Здравствуйте, mkizub, Вы писали:

M>>>Это вообще не язык. Это концепция (парадигма) программирования (с упором на мета-программирование) и его реализация.


CU>>Это пока ещё только концепция и ничего больше.

CU>>Так и запишем: "Лисп — ассемблер в МП. Но С ещё не придумали..."

M>По первых — реализация, пусть и в стадии prrof-of-concept.


Хрен редьки не слаще. Ваш концепт только и доказывает что возможность частичной реализации Вашей-же идеи. Всё. С практической точки зрения — 0.

M>Во вторых — уже придумали.


"Имя, сестра, имя!"
Re[12]: Являются ли макросы свидетельством недостаточной выр
От: cl-user  
Дата: 10.08.07 07:06
Оценка:
Здравствуйте, FR, Вы писали:

CU>>"Памяти мало, на скорость положить" — слишком узкий спектр задач. Даже в мобилку не пойдёт. Вот и остаётся только что засовывать в медленные но хитрые контроллеры да в бутромы всякие — скорость загрузки не критична.


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


Он медленнее любых "прямых" компиляторов в натив. Даже SBCL его обгоняет. Так нафига? Только из-за памяти.
Re[14]: Являются ли макросы свидетельством недостаточной выр
От: mkizub Литва http://symade.tigris.org
Дата: 10.08.07 08:52
Оценка:
Здравствуйте, FR, Вы писали:

FR>Не будет не из-за этого, а из-за того что место давно занято.


Ага, а когда оно было свободным — помешал всемирный еврейский заговор.

FR>Угу то-то эта ява так страшно тормозит.


"Страшно" тормозящую яву я видел только одну — неоптимизированный C-шный main loop по байткоду, который поставляется фирмой Sun, для а) отладки, и б) пусть каждый оптимизирует под свой процессор как хочет.
Именно эту работу я делал для Samsung-овский телефонов и digital TV — переписывал main loop на асме, что за неделю работы дало ускорение в 2 раза. Ещё в два раза дало ускорение оптимизация вызова методов и выкидывание некоторых "дублирующих" инструкций (вроде op_null и op_const0) и использование освободившегося места для комбинированных инструкций.

FR>"Интерпретор" у форта как ты наверно знаешь, имеет некторые особенности которые позволяют ему по скорости мало уступать тупым плохо оптимизирующим компиляторам (а явовские в мобилках именно такие), правда эти же особенности мешают построить хороший оптимизирующий компилятор. Но компиляторы у форта есть и посоревноватся с той же явой вполне могут.


Этого не может быть, потому, что этого не может быть никогда.
Любой, самый тупой из тупых компиляторов разворачивает байткод в последовательность комманд процессора, экономя на каждой комманде чтение опкода и джамп на хэндлер. У ARM эти две операции совмещены, но джамп занимает больше такта. У MIPS их надо делать отдельно, но он выполняет ещё одну инструкцию, в течении джампа. Итого — минимальная прибыль от компилятора, даже если он тупо работает со стеком и не занимается регистрами — 2-3 такта на инстукцию. Если он ещё регистры использует (даже без оптимизации) — то это ещё раза в 2 ускорение.

Фсё, я тему быстродействия больше в этом топике не обсуждаю. Если есть что-то конкретное в виде бенчмарков — можно обсудить в новом топике.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.