Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Ок, Влад, ты меня убедил, информация о типах здесь очень важна и нужна (хотя я и раньше не сильно сопротивлялся этому).
Ну, слава богу, хотя бы по этому вопросу ты со сной согласен. Уже огромное продвижение, так как гостпода вроде Turtle.BAZON.Group даже этого признавать не хотят.
LCR>Тем не менее в Лиспе информация о типах тоже есть,
К сожалению, это не так. И на то есть ряд объективных причин. Главная из которых нетипизированность Лиспа.
LCR>взгляни: LCR>
LCR>CL-USER 1 > (defstruct point x y z)
LCR>POINT
...
LCR>CL-USER 4 > (setf my-point (make-point :x 3 :y 4 :z 12))
LCR>#S(POINT X 3 Y 4 Z 12)
...
LCR>CL-USER 5 > (type-of my-point)
LCR>POINT
LCR>
LCR>(всё это легко посмотреть прямо в лиспбоксе)
Меня за идиота считают? Или рассчет на то, что я настолько не компетентен в Лиспе, что проглачу даже это?
1. Функция type-of — возвращает тип объекта, то есть она с огромной натяжкой (об этом позже) аналогична методу GetType() в дотнете. Меж тем для макросов важно получение информации о типах во время компиляции (во время выполенения макроса). При этом информация о типах нужна для выражений (а не результата их исполнения, которых просто нет к этому моменту).
2. В CL эта функция для структур и других определяемых пользователями типов возрващает их имя. И что с ним делать дальше? Это соврешенно бесполезная информация.
3. Кроме получения информации о типе конкретного выражения (что уже в общем случае нельзя сделать на Лиспе) нужно иметь возможность получать информацию о типах объевленных в программе.
В общем, давай я продемонстрирую что делает тот же макрос SupportRelocation на примере.
Будучи объявленным в качестве атрибута на классе TypeBuilder:
[Nemerle.Compiler.SupportRelocation]
public partial class TypeBuilder : TypeInfo
{
....
}
он вызывается во время компиляции и приводит к тому, что к каждому классу добавляется реализация метода:
[CompilerGenerated]
internal override void RelocateImplInternal(RelocationInfo info)
{
... // код этого метода генерируется на основании информации о типе того типа
// к которому добавляется этот метод.
}
Внутри этого метода генерируется код объхода всех объектов на которые ссылается данный объект (в том числе и списков). Для каждого такого объекта (если его тип не включен в список игнорируемых) вызвается метод RelocateImplInternal() (который так же генерируется этим же макросом).
Кроме того для каждоого поля объявленного в этом типе имеющем тип Location генерируется код следующего вида:
info — это объект содержащий данные для пересчета (смещение и т.п.). А Completion.Relocate() — это функция пересчета.
Для списочных полей надо сгенерировать код типа:
Здравствуйте, FR, Вы писали:
FR>По моему самый интересный из лиспов, вернее его потомков это QI (http://www.lambdassociates.org/) уже вполне удобный и понятный язык там и типизация есть и паттерн матчинг и макросы. В общем очень интересная штучка. Можно с ним сравнить, правда я глубоко еще не ковырялся.
Как наковыряшься — отпиши о впечатлениях
На вскидку — из-за изменения синтаксиса не все возможности имплементированы (или я не дочитал до конца или пропустил что-то ) А использовать кашу из лиспа и Qi — это ещё тот "венегрет" получится
Здравствуйте, VladD2, Вы писали:
VD>Ну, слава богу, хотя бы по этому вопросу ты со сной согласен. Уже огромное продвижение, так как гостпода вроде Turtle.BAZON.Group даже этого признавать не хотят.
Вы потомственный телепат? Если да, то гены ваши давно испортились.
VD>Меня за идиота считают? Или рассчет на то, что я настолько не компетентен в Лиспе, что проглачу даже это?
С Вашей стороны не менее всяких уловок. Будет время — отпишу подробнее.
Здравствуйте, VladD2, Вы писали:
TBG>>но Влад выбрал неудачный пример. VD>Я выбрал пример из статьи одного из проповедников Схемы.
Говорю же — неудачный.
VD>Вы твту в один голос кричите, что мол Лисп проще, Лисп круче, а на самом деле это далеко не так. Как минимум он может соревнаваться на равный. А учитывая прочее, он вообще частенько будет в аутсайдерах.
Лично я ничего не говорю. Я спрашиваю, с чего это вдруг макросы лиспа послабее будут? Уже читая тот опус, который поскипан, можно сказать, что не будут они мощнее, поскольку немерле кастрировал макросистемы всех языков, а не только учитывал их ошибки.
Здравствуйте, FR, Вы писали:
FR>По моему самый интересный из лиспов, вернее его потомков это QI (http://www.lambdassociates.org/) уже вполне удобный и понятный язык там и типизация есть и паттерн матчинг и макросы. В общем очень интересная штучка. Можно с ним сравнить, правда я глубоко еще не ковырялся.
Посмотрел чуть глубже...
Мне бы больше понравилось, если бы его можно было использовать как модуль + с локальным переопределением синтаксиса. Надо будет подумать...
Здравствуйте, Turtle.BAZON.Group, Вы писали:
TBG>Здравствуйте, VladD2, Вы писали:
VD>>Ну, слава богу, хотя бы по этому вопросу ты со сной согласен. Уже огромное продвижение, так как гостпода вроде Turtle.BAZON.Group даже этого признавать не хотят.
TBG>Вы потомственный телепат? Если да, то гены ваши давно испортились.
Этот наезд можно интерпретировать как согласие со мной?
А телепатом тут быть не надо. Ты во всю тут утверждаешь, что информация о типах в макросах как бы ненужна. И отказыаешся считать ее наличие приемуществом. Если это не так и я ошибаюсь, ты только скажи. Только зачем надо было спорить тут столько?
VD>>Меня за идиота считают? Или рассчет на то, что я настолько не компетентен в Лиспе, что проглачу даже это?
TBG>С Вашей стороны не менее всяких уловок.
Не надо песен.
TBG>Будет время — отпишу подробнее.
Вот будет время — пиши... по делу. А гнелвые без почвенные обвинения будь добр оставлять при себе. Надоело, знаете ли.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Turtle.BAZON.Group, Вы писали:
VD>>Вы твту в один голос кричите, что мол Лисп проще, Лисп круче, а на самом деле это далеко не так. Как минимум он может соревнаваться на равный. А учитывая прочее, он вообще частенько будет в аутсайдерах.
TBG>Лично я ничего не говорю. Я спрашиваю, с чего это вдруг макросы лиспа послабее будут?
А тебе и отвечают НЕТ ВОЗМОЖНОСТИ ПОЛУЧАТЬ И ИСПОЛЬЗОВАТЬ ИНФОРМАЦИЮ О ТИПАХ. Но ты так истенный Блаб-программист в упор не хочешь видеть, что это дает огромные приемущества. И даже еще в наглую умедряешся
рассуждать о моей телепатии когда я говорю об этом.
TBG>Уже читая тот опус, который поскипан, можно сказать, что не будут они мощнее, поскольку немерле кастрировал макросистемы всех языков, а не только учитывал их ошибки.
Извини, но общасться с людми не приводящими никаких аргументов, плющимися во все стороны и не способными к непредвзятой и адекватной оценке мне не интересно.
Всего доброго.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
TBG>>Вы потомственный телепат? Если да, то гены ваши давно испортились. VD>Этот наезд можно интерпретировать как согласие со мной?
Это не наезд. И можно интерпретировать только как отсустствие способностей этих у вас как таковых.
VD>А телепатом тут быть не надо. Ты во всю тут утверждаешь, что информация о типах в макросах как бы ненужна. И отказыаешся считать ее наличие приемуществом. Если это не так и я ошибаюсь, ты только скажи. Только зачем надо было спорить тут столько?
Цитаты? Я не утвреждаю, что информация о типах не нужна. Я говорю о том, что наличием/отсутствием этого нельзя мерить мощность макросистем.
[наезды поскипаны]
TBG>>Будет время — отпишу подробнее. VD>Вот будет время — пиши... по делу. А гнелвые без почвенные обвинения будь добр оставлять при себе. Надоело, знаете ли.
Покажите "гнелвые без почвенные обвинения" прежде чем это утвержать. С Вашей стороны только видно, что преимущества в строгой типизированности языка и следствие мощности макросистемы. Больше аргументов никаких. Антинаучно как минимум.
Здравствуйте, VladD2, Вы писали:
TBG>>Лично я ничего не говорю. Я спрашиваю, с чего это вдруг макросы лиспа послабее будут? VD>А тебе и отвечают НЕТ ВОЗМОЖНОСТИ ПОЛУЧАТЬ И ИСПОЛЬЗОВАТЬ ИНФОРМАЦИЮ О ТИПАХ. Но ты так истенный Блаб-программист в упор не хочешь
Так я и говорю, что помимо информации о типах есть еще что-нибудь? Либо тогда послабее в плане типов систем. Но не слабее как таковые.
VD>видеть, что это дает огромные приемущества.
Огромные не огромные, кое-какие возможости дает. Я этого не отрицаю. Но типизация — не единственное мерило макросистем.
[наезды поскипаны]
VD>Извини, но общасться с людми не приводящими никаких аргументов, плющимися во все стороны и не способными к непредвзятой и адекватной оценке мне не интересно.
Здравствуйте, Turtle.BAZON.Group, Вы писали:
TBG>Покажите "гнелвые без почвенные обвинения" прежде чем это утвержать. С Вашей стороны только видно, что преимущества в строгой типизированности языка и следствие мощности макросистемы. Больше аргументов никаких. Антинаучно как минимум.
Грэхэма бы сюда. Вот он бы оржал над тем как Лисп-программист стал Блаб-программистом.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Забей. (Если Влад чего-то там не так сказал, то совсем необязательно, что ты тому причина. Тем более слова "меня за идиота считают?" вроде как предназначались мне и я их собирался проигнорировать. )
располагается несколько ниже. Там есть макрос SupportRelocation, и я думаю, как на Лиспе сделать такой же фокус. Это определённо, 100% возможно, просто меня интересует, как это сделать проще всего. Если есть какие-нть идеи, то пожалуйста. Думаю, будет интересно не только мне.
TBG> С Вашей стороны только видно, что преимущества в строгой типизированности языка и следствие мощности макросистемы. Больше аргументов никаких. Антинаучно как минимум.
Хм. У "Не-макросов" есть некоторые особенности, которые как минимум интересны.
1. Выделение развёртывания макросов в отдельную стадию;
2. В процессе развёртки можно использовать библиотеки;
3. При этом в макросах можно попросить компилятор вычислить тип выражения (и даже чуть больше — см SupportRelocation), что отличает "Не-макросы" от "интеллектуальных" препроцессоров.
Как видим, 2-й пункт подобен возможностям в Лиспе. Но 1-й пункт представляет собой весьма жосткое ограничение. И я нашёл контрпример, классический макрос once-only:
(defmacro once-only ((&rest names) &body body)
(let ((gensyms (loop for n in names collect (gensym))))
`(let (,@(loop for g in gensyms collect `(,g (gensym))))
`(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
,@body)))))
Вот здесь Немерле приплыл.
Теперь давай покажем что тот особенный 3-й пункт реализуем в Лиспе — и дело в шляпе!
располагается несколько ниже. Там есть макрос SupportRelocation, и я думаю, как на Лиспе сделать такой же фокус. Это определённо, 100% возможно, просто меня интересует, как это сделать проще всего.
Да, элементарно. Что там делать то? Пишите "думатель" (с) ц-саил. Он быстренько анализирует код на Лиспе, выводит типы (сам). Вы их берете и через 24 как... (с).
LCR>Как видим, 2-й пункт подобен возможностям в Лиспе. Но 1-й пункт представляет собой весьма жосткое ограничение. И я нашёл контрпример, классический макрос once-only: LCR>
LCR>(defmacro once-only ((&rest names) &body body)
LCR> (let ((gensyms (loop for n in names collect (gensym))))
LCR> `(let (,@(loop for g in gensyms collect `(,g (gensym))))
LCR> `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
LCR> ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
LCR> ,@body)))))
LCR>
LCR>Вот здесь Немерле приплыл.
LCR>Теперь давай покажем что тот особенный 3-й пункт реализуем в Лиспе — и дело в шляпе!
Не реализуем, не реализуем. Лучше объясни что делает приведенная выше каша. Может я тебе все же покажу как Немерле выплывет обратно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>3. При этом в макросах можно попросить компилятор вычислить тип выражения (и даже чуть больше — см SupportRelocation), что отличает "Не-макросы" от "интеллектуальных" препроцессоров.
Я, конечно, не до конца понимаю что хочет Влад и при его тоне как-то не сильно хочется разбираться, но думаю, все. что ему необходимо, доступно с использованием Meta Object Protocol.
VladD2 wrote: > LCR>(defmacro once-only ((&rest names) &body body) > LCR> (let ((gensyms (loop for n in names collect (gensym)))) > LCR> `(let (,@(loop for g in gensyms collect `(,g (gensym)))) > LCR> `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n))) > LCR> ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g))) > LCR> ,@body))))) > LCR> > > LCR>Вот здесь Немерле приплыл. > > LCR>Теперь давай покажем что тот особенный 3-й пункт реализуем в Лиспе — > и дело в шляпе! > > Не реализуем, не реализуем. Лучше объясни что делает приведенная выше > каша. Может я тебе все же покажу как Немерле выплывет обратно.
Этот код делает следующее:
(defmacro sqr (x) `(* ,x ,x)) вычислит x (например, (random 100)) два
раза независимо. (defmacro sqr (x) (once-only (x) `(* ,x ,x))) всегда
вычислит x один раз. Этот пример, кстати, переписать на Nemerle должно
быть относительно легко. Идея приведённого кода в том, что (let ((x
'(random 100))) `(* ,x ,x)) заменяется на (let ((x '(random 100))) `(let
((y ,x)) (let ((x y)) `(* ,x ,x)))) — внутренне выражение этого не замечает.
Здесь "`()" означает квазицитирование, а "," его снятие.
Здравствуйте, raskin, Вы писали:
R>Этот код делает следующее: R>(defmacro sqr (x) `(* ,x ,x)) вычислит x (например, (random 100)) два R>раза независимо. (defmacro sqr (x) (once-only (x) `(* ,x ,x))) всегда R>вычислит x один раз. Этот пример, кстати, переписать на Nemerle должно R>быть относительно легко. Идея приведённого кода в том, что (let ((x R>'(random 100))) `(* ,x ,x)) заменяется на (let ((x '(random 100))) `(let R>((y ,x)) (let ((x y)) `(* ,x ,x)))) — внутренне выражение этого не замечает. R>Здесь "`()" означает квазицитирование, а "," его снятие.
Ясно.Это действительно переписывается на Непрле. Многие считаю, что раз нелзя рекурсивно вызвать макросы, то это приговор. Меж тем, кодом могут манипулировать любые функции. Макрос — это только точка входа в мета-слой. Квази-цитирование тоже доступно где угодно. И применять его можно как для конструирования выражений, так и дял их декомпозиции.
Кстати, похожая вещь исползуется в Немерлевом макросе <-> производящем обмен значений местами (аналог фукнции swap(y, y). И в операторах типа "+=".
В немерле остановить вычисление в принципе можно просто присвоив его некой переменной. Так что в общем-то казалось бы достаточно породить код типа этого:
<[ def x = $expr; ]>
И дело в шляпе. Но к сожалению expr может мыть массивом с динамической индесацией. Например:
aArray[rand()] <-> aArray[rand()]
при таком раскладе, просто присвоение переменной уже не поможет. Приходится извертываться сложнее.
Вот как выглядит код макроса реализующего оператор <->: