LINUX.ORG.RU

Сетевые игры на основе лиспа


0

1

Здравствуйте, вот сидел сегодня и задумался о том как сделать сетевую игру с помощью лиспа. Ничего сложно не охота так просто для начала крестики нолики. Да я понимаю что в сети всего этого полно и даже онлайн есть, но охота реализовать самому и посмотреть насколько легко справится лисп(вернее я справлюсь с помощью лиспа) сам по себе конечно код тривиальный если просто играть по очереди одной мышкой... Но охота связаться с человеком который в локальной сети сидит и который может сидеть на другом конце страны... как это реализовать? Ща вот полазил по нигме с запросом «Сетевые игры на лиспе» и подобные запросы. Мне ничего не выдало кроме того как создать сайт на лиспе. С чего начать, может кто то статью знает с примерами или книгу? А может на лиспе всё это дело слишком сложно и не стоит заморачиваться?

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

> Да, с define разобрался. Как примитив на уровне реализации - может быть, но вообще это лишний примитив - есть let.

let как раз лишний, есть lambda =)

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

Я бы сказал восхитительно)))) Хотя не понимаю зачем вообще в лиспе разбивать программы на отдельные файлы? Нет ну понимаю когда строк за 1000 переваливает, но в такой маленькой... наверное это дело привычки... И я хотел не те крестики нолики))) Я хотел... по моиму это называется шашки «го» то есть там где нужно 5 крестиков в линию выстроить, то есть поле должно быть динамическим. но это всё в принципе решаемо, попробую дома сделать то что вы написали, и разобраться. А прикрутить более большой «мир» это уже второстепенно.

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

> 5 крестиков в линию выстроить

У игры есть выигрышная стратегия для первого игрока. Лучше действительно сделай го.

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

> Приводите контрпример.

Ну так я привел. Любой более-менее сложный макрос так делает. Ну я по крайней мере не видел тех, которые не делают.

Я утверждаю, что все пряморукие реализации делают стандартные макрос функциями вида AST->AST которые не имеют побочных эффектов на этапе раскрытия

Да утверждайте сколько хотите. Реальность то от ваших утверждений не изменится. Вона, раньше что утверждали, - Земля плоская, мол.

ничего не делает кроме генерации кода (который уже имеет влияние на рантайм).

Во-первых, макрос - не функция. И не может быть исследован как функция. Даже чистый макрос аст->аст может иметь сайдэффекты, например макрос, который раскрывается в (defun ...) имеет сайдэффекты, потому что он влияет на раскрытие последующих макросов (точнее говоря сайдэффекты имеет макрос defun, как и любой макрос, в которой используется eval-when, ну а дальше все просто - любой макрос, раскрывающийся в макрос с сайд-эффектами, сам имеет сайд-эффекты). Но про CL говорить несколько сложно - потому что у него нету разделения между рантаймом и компайлтаймом. Вы всегда можете сказать «а на самом деле это рантайм» - возьмем ту же Racket, у нее уже есть четкое разделение по фазам. Вот подобные макросы там используются для создания структур, например. Ну и, наконец, эти макросы имеют непосредственную связь с тем, о чем мы говорим - получении гарантий корректности при помощи макросов. Только благодаря им это возможно. И только благодаря им в рамках любой макросистемы можно реализовать любую систему типов.

Ага, знать все типы на этапе компиляции - действительно, кому это нужно? :) Schemer-ам не нужно? Вот в GCC - нужно, можно ведь не boxed integer неограниченной длинны вида:

Как связан тайпинференс со знанием всех типов на этапе компиляции? Ответ - никак. В GCC вообще никакго тайпинференса нету и никогда не было и прекрасно все типы известны. повторяю - _полный_ тайпинференс чрезвычайно вреден с практической точки зрения. Это уже давно общеизвестный факт.

Это в scheme ;) Во всём остальном мире nested pattern matching ... и тут длинная такая хреновина с огромным количеством CASE-оф.

Нет, это как раз во всем мире, а не в Scheme. потому что паттерн-матчинг появился исторически эдак на полстолетия позже if-а и выражался в терминах if-ов.

И кроме case-оф ничего больше не нужно.

Ну да. Есть if, через него тривиально выражаем case и далее используем где удобно case вместо if-а :)

Нет.

Да.

Какая разница?

Ну так это все костыли, мы же в общем говорим? Кто вам мешает использовать ту же функцию для if-предиката, что используется в case? Никто. Более того - именно так и выражается case (через if в котором соответствующий предикат).

Ну раз миграция идей отсутсвует по вашему - то, наверное, не важно.

Ну раз сказали А, то говорите Б.

Также очевидно, что база CS общая для разных языков

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

Точно, абсолютно по разному решаются одни и те же задичи. Какой curring, point free, рекурсия и ФВП - есть же итераторы! :)

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

А есть нормальная и открытая для CL?

Что значит «нормальная»? :)

Это ведь был бы очевидный профит для качества кодогенерации (да и для проверок на некий класс ошибок).

Не был бы. Я вам повторяю - в лиспе это НЕ НУЖНО. Не надо делать из лиспа хаскель, пишите на лиспе как на лиспе, а не как на хаскеле. Выйдите из своего хаски-мирка :)

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

> Да, с define разобрался. Как примитив на уровне реализации - может быть, но вообще это лишний примитив - есть let.

Угу, дефайн меняем на let, let легко превращаем в лямбду, потом меняем порядок вычислений на нормальный, чтобы можно было убрать из спецформ if, ну а раз порядок нормальный - то нет set-у! остается чистое лямбда-исчисление :)

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

>> Также очевидно, что база CS общая для разных языков

Нет, в ней нету ничего общего.

Афигеть. У CL даже CS своя %)

tailgunner ★★★★★
()

Macil, выходи по шапке получать - пришёл Царь Тьмы Анонимной, покровитель лисперов.

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

> Афигеть. У CL даже CS своя %)

Во-первых, я говорил про лисп, а не про CL, а во-вторых - не своя, а вполне обычная. Просто CS не ограничивается тем набором методов, что применяется в хаскеле (но я уже говорил о том, что любители хаскиля за пределами своего хаскимирка упорно ничего не видят). А если уж на то пошло, то исторически будет корректнее «у хаскеля даже CS своя» ;)

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

Анонимус, с которым я спорю про if, case, чистоту макросов и т.п. - твоя упёртость достойна восхишения :) #redirect к моим предыдущим постам, больше мне сказать нечего (а то уже на второй круг заходите) - там есть ответы на вопросы «почему макрос - функция (см. CLHS: macro-function)», «почему все стандартные и библиотечные макросы не имеют сайд-эффектов (записи!) времени макроэкспансии (см. примеры раскрытия - funcall на macro-function)», «почему case место в core, а if нет - потому что это тупо и более общий и более эффективный с точки зрения реализации подход».

Как связан тайпинференс со знанием всех типов на этапе компиляции?

Знание статической информации о типах не позволяет генерировать лучший код? Это же прописная истина.

Нет, это как раз во всем мире, а не в Scheme. потому что паттерн-матчинг появился исторически эдак на полстолетия позже if-а и выражался в терминах if-ов.

Да чего уж там, мне вообще кроме JMP тогда ничего не нужно - пресловутые «циклы/ветвления/следования» через них выражаются.

Нет, в ней нету ничего общего.

Вот я и смотрю - очень трудно договариаться.

Выйдите из своего хаски-мирка :)

О, я буду теперь вещать из своего «хаски-мирка» :)

На самом деле, я вполне понимаю такую картину мира - динамика, предикаты по типам + if-ы как примитивы. Вот в CL - if это примитив, а cond / case / typecase производные формы и есть предикаты по значенияи / типам. Т.е. всё так как вы говорите. Но я исхожу всё-таки из общей для разных языков базы и сознательно не использую (уже) такую картину мира - использую другую, отсюда такой спор.

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

let как раз лишний, есть lambda =)

Ну, есть же косяки с выражением let через lambda, которые заставляют добавить его как примитив.

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

Хотя не понимаю зачем вообще в лиспе разбивать программы на отдельные файлы?

Ну как обычно - сюда будет складывать классы игрового мира, а сюда сетевые функции, а сюда... И так далее. Это же зарисовка (там кстати sexp-вещи в data.lisp не нужны - надо выкинуть, и сериализовать можно по-другому) - в расчёте на то, что будет обрастать кодом.

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

> «почему макрос - функция (см. CLHS: macro-function)»

Функция, но не чистая.

«почему все стандартные и библиотечные макросы не имеют сайд-эффектов (записи!) времени макроэкспансии (см. примеры раскрытия - funcall на macro-function)»

Они используют, я вам уже привел конкретные примеры - пекеджи, defun, defmacro. Неужели так трудно самому посмотреть на результат макроэкспанда?

Знание статической информации о типах не позволяет генерировать лучший код?

Вы еврей? Каким боком генерация лучшего кода относится к связи тайпинференса со знанием типов на этапе компиляции?

Да чего уж там, мне вообще кроме JMP тогда ничего не нужно - пресловутые «циклы/ветвления/следования» через них выражаются.

только следования.

Но я исхожу всё-таки из общей для разных языков базы

Ее нет. Кстати, зачем вообще в хаскиль-core паттерн-матчинг? Хаскиль же ленивый, там не if-а ни паттерн-матчинга не надо - оно выражается в терминах языка.

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

> Ну, есть же косяки с выражением let через lambda, которые заставляют добавить его как примитив.

Ну просто выразить несколько сложнее, но можно. В том же r5rs примитивы - set!, lambda, app, if. let - derived-форма.

Да, кстати:

почему все стандартные и библиотечные макросы не имеют сайд-эффектов

Даже если где-то (не в CL явно) и не имеют - это проблема ЯП, в котором не имеют. Потому что, во-первых, сайд-эффекты кардинально расширяют возможности макросистемы, а во-вторых очень сильно снижают вероятность незаметить ошибку. Фактически, если вы пишете сложный дсл и много работаете с контекстом - то первый же удачный макроэкспанд гарантирует, что ошибок нет :)

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

Они используют, я вам уже привел конкретные примеры - пекеджи, defun, defmacro. Неужели так трудно самому посмотреть на результат макроэкспанда?

Неужели так трудно читать чужие сообщения? Коню понятно, что в результате раскрытия может получится код с сайд эффектами. Я всё твержу, что _до_ обратной кавычки, т.е. во время генерации сайд-эффектов записи нет и поэтому макрос это чистая функция AST -> AST (точнее, она может быть и не чистой, но _не принято_ что-то менять на стадии генерации - нигде в нормальном коде нет таких макросов).

Каким боком генерация лучшего кода относится к связи тайпинференса со знанием типов на этапе компиляции?

Тут я потерял нить обсуждения, кажется. Извиняюсь.

Кстати, зачем вообще в хаскиль-core паттерн-матчинг?

[позевает] в хаскиль-core его и нет, блин :) там case в который этот паттерн-матчинг (сахар!) превращается.

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

> И 32 бита. По нынешним временам - не серьезно.

притом, что оригинальный SML/NJ спокойно работает с 64 битами, а в Mythryl что-то сломали.

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

почему все стандартные и библиотечные макросы не имеют сайд-эффектов

Даже если где-то (не в CL явно) и не имеют - это проблема ЯП, в котором не имеют.

не про то - код который они генерируют имеет сайд-эффекты. код который осуществляет эту генерацию может иметь сайд-эффекты - но так не принято (ну типа макрос расрывается и куда-то пишет - «я раскрываюся!», прямо в время экспанда).

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

Хаскиль же ленивый, там не if-а ни паттерн-матчинга не надо - оно выражается в терминах языка.

Ха! Неужели так трудно читать чужие сообщения? :)

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

>>сюда же можно записать и Guile

Guile какбы породистая R5RS Схема. Так что точно не сюда.


cхема, но ближе к скриптовому языку. Вот например флейм был про Tcl wars: http://www.vanderburg.org/OldPages/Tcl/war/ — Столман обосрал Tcl, и ничего разумного не ответил.
Хотя планов было громадьё.. вот например, C язычок встроить, CTAX http://theory.uwinnipeg.ca/localfiles/infofiles/guile/ctax_toc.html пакет guile-lang-allover мейллист http://www.red-bean.com/guile/guile/old/2940.html

И ниша у Guile скорее скриптовая.

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

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

проще всего, IMHO, прикрутить джаббер и trivial-xmpp.
Крестики-нолики через джаббер.

anonymous
()

> лямбда-куб

прочитал как «лямбда-кун»

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

> eval-when - условие на состояние окружающего мира. Как если бы в макросе был код (if *config* ...) - зависимость от внешней переменной.

Это софистика. Давайте возьмем некоторый макрос, который работает с внешним миром. Допустим, его тело - (body ...). Теперь заменим тело на: `(eval-when `(body ...)) (at-compile и прочее не пишу - и так понятно). Этот макрос будет работать _точно так же_, но по вашей логике, он уже не имеет сайдэффектов. И так можно поступить с любым, абсолютно с любым макросом. Ну и повторю - у CL нету разницы между компиляцией и рантаймом.

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

> т.е. во время генерации сайд-эффектов записи нет и поэтому макрос это чистая функция AST -> AST

Вот вопрос - (setq *param* ...) этот код что делает? Ну всмысле, меняет значение какойто переменной в нашей программе, или меняет состояние среды (то есть тот самый контекст компиляции)? В CL ответить нельзя. потому что нету разницы. И по-этому применительно к CL это все несколько бессмысленно.

но _не принято_ что-то менять на стадии генерации

Потому что у CL нету стадии генерации. то есть ее никак нельзя отличить от стадии исполнения программы.

в хаскиль-core его и нет, блин :) там case в который этот паттерн-матчинг (сахар!) превращается.

Ну раз это только сахар, то зачем их различать? Я говорю о том, что там не нужен ни кейз, ни иф, ни паттерн-матчинг вообще.

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

> В LC при наличии любой простейшей системы типов А при чем тут система типов?

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

> В LC при наличии любой простейшей системы типов (TAPL 11.5 и ITFP 4.2.1).

не знаю как там в хаскелле, но, что в Схеме, что в CL, let выражается через lambda

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

>Потому что у CL нету стадии генерации. то есть ее никак нельзя отличить от стадии исполнения программы.

Да сдохни ты уж поскорее в своём невежестве (или косноязычии - хз)

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

Иди учи матчасть. В CL нету никакой разницы между чтением, экспандом, компиляцией и т.д.. Все эти функции (read, expand, compile, eval) запускаются в том же окружении и точно так же как любая другая ф-я. И никак нельзя отличить вызов read руками от автоматического вызова read реплом. То есть есть только одна стадия - исполнение программы (а точнее работа рантайма лисп-машины).

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

Давайте возьмем некоторый макрос, который работает с внешним миром.

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

Вот вопрос - (setq *param* ...) этот код что делает?

(setq *param* ...) в макросе? (надеюсь *param* определена в defvar/defparameter).

Ваш setq в таком гипотетическом макросе до обратной кавычки? Если да, то нафига (и пример такого макроса IRL)? Если под обратной кавычкой, то побочный эффект имеет генерируемый код, а не макрос - сделайте macroexpand (или funcall на macro-function, т.е. то что делает macroexpand) и убедитесь, что *param* не определилась. Чистота?

Я говорю о том, что там не нужен ни кейз, ни иф, ни паттерн-матчинг вообще.

Всё уже решили за вас :)

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

Но я исхожу всё-таки из общей для разных языков базы

Ее нет.

Т.е. за over 60 лет не появилась академическая наука - теория языков и счислений, автоматов, грамматики Хомского (семантические атрибуты Кнута), теория типов?

Вот TAPL - ей, по вашему, можно верить или нет? Если что, то там изучаются языки разных типов - безопасные статические (ML, Haskell, Java), безопасные динамические (Lisp*, JavaScript), небезопасные статические (C, C++). Для изучения используется символический язык основанный на математическом (теория множеств, абстрактная алгебра, теория категорий) - можно им оперировать непосредственно (без привлечения конкретно математики).

Мне кажется, нельзя использовать понятия принятые в каком-то конкретном ЯП и ими мерить все остальные языки.

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

>Потому что у CL нету стадии генерации.

В CL нету никакой разницы между чтением, экспандом, компиляцией и т.д..


косноязычный идиот

про eval-when знаешь? Я в курсе, что на любом этапе можно запускать read, expand, compile, eval. Но наличие _детерминированных_ стадий компиляции/загрузки/выполнения с чётко очерченными возможностями это не отменяет. А для того чтобы себе х..й сломать CL не нужен.

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

>Ну как обычно - сюда будет складывать классы игрового мира, а сюда сетевые функции, а сюда... И так далее. Это же зарисовка (там кстати sexp-вещи в data.lisp не нужны - надо выкинуть, и сериализовать можно по-другому) - в расчёте на то, что будет обрастать кодом.

Мысль понял, жду не дождусь выходных. Уже не терпится начать)))

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

> Только какое отношение эти книжки имеют к хаскелю?

А при чем тут хаскель, если речь шла о лиспе?

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

> Но наличие _детерминированных_ стадий компиляции/загрузки/выполнения с чётко очерченными возможностями это не отменяет.

Хватит тупить уже. Иди читай стандарт, в CL никаких «стадий» нету. Есть набор некоторых функций, и под «стадией» подразумевается выполнение этой самой ф-и (тот же евал, компайл и т.п.). Но эти ф-и могут быть выполнены в любой произвольный момент (в том числе во время вызова какой-то другой ф-и). Если вызван read, во время которого вызван компайл, во время которого вызван евал, во время которого вызван компайл - это какая стадия?

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

> Мне кажется, нельзя использовать понятия принятые в каком-то конкретном ЯП и ими мерить все остальные языки.

Конечно, кажется. И я в упор не могу понять, почему любители хаскеля все время это делают.

Т.е. за over 60 лет не появилась академическая наука - теория языков и счислений, автоматов, грамматики Хомского (семантические атрибуты Кнута), теория типов?

Не надо путать. Хаскель - это именно теория типов и иже с ней, и 99% современного CS - это теория типов и иже с ней. Хаскель без теории типов - ничто. Он на ней основан. А к лиспу теория типов никак неприменима. О чем и шла речь. Если бы вы читали хоть пару работ по лиспу, то увидели бы, что в них нет ничего общего с хаскеле-CSом, даже тогда, когда заходит речь о всякого рода типах - там используются совершенно иные подходы, о которых вы в том же тапле не прочитаете. В общем научная база у них прицнипиально различна, причем то, что используется для хскеля неприменимо в рамках лиспа и наоборот. Есть, конечно, некоторые общие основы (типа тех же грамматик, например), но они сами по себе несодержательны. Да вот взят хотя бы - лисп всегда исследуется в рамках операционной семантики. Кто-нибудь видел операционную семантику Хаскеля? Вопрос - возможно ли вообще ее написать.

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

> Конечно, кажется.

Мне тоже кажется. Быстрофикс.

anonymous
()

А чего ты ожидал от семейства языков с названием LISP? Тебе определенно нужен GAMP.

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

> Ага, в духе заблуждений «если вы чего-то не можете - не проблема, всегда можно написать макрос, макросы решат все проблемы».

Хорошо, я буду на примерах. Возьмем макрос: (define-syntax (yoba stx) (display 100) #`(void)) Этот макрос работает с внешним миром (выводит 100 во время 1 фазы, когда макрос раскрывается). Теперь: (define-syntax (yoba stx) #`(begin-for-syntax (display 100) #`(void))) Этот макрос делает _в точности_ то же самое, что и первыЙ, но по вашей дикой логике, сайдэффектов в нем уже нет. И зачем мне писать #`(begin-for-syntax (display 100) #`(void)), если я могу написать просто (display 100) #`(void) - это и короче и понятнее и удобнее?

Макросы с кодом работают а не с миром (и на рантайм «немножко» завязаны). С миром работают нормальные функции и методы.

Вы же сами только что говорили, что макрос - это и есть обычная «нормальная» функция? Так вот, обычные, «нормальные» функции могут работать только с рантаймом, но они не могут работать с контекстом экспанда. У CL рантайм = контекст экспанда, в CL вообще есть только один контекст, который всегда и отовсюду доступен.

(setq *param* ...) в макросе? (надеюсь *param* определена в defvar/defparameter). Ваш setq в таком гипотетическом макросе до обратной кавычки?

Так о чем и речь. (defmacro yoba () (setq *param* ...)) и (defmacro yoba () `(setq *param* ...)) это в CL _одно и то же_ (если формы исполняются в топ-левеле).

(и пример такого макроса IRL)?

Любой макрос, который делает setq в eval-when.

В общем меня это утомило. Повторю еще раз - если в каком-то языке сайдэффекты в макросах не используются - это проблема данного языка. Зачем лишать себя мощного и удобного инструмента?

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

А вообще - давайте определимся сперва, что значит «макрос с сайдэффектами». Я предлагаю такое определение - форма f является «макросом с сайдэффектами», если сайдэффект имеет (compile 'f). Согласны (другими словами - обычная ф-я имеет сайдэффекты если взаимодействует с миром во время eval, макрос имеет сайдэффекты, если взаимодействует с миров во время compile)?

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

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

Я вообще не вижу никакой _своей_ «научной базы» у распространённых лиспов - просто здоровый инженерный подход, а всё остальное - общее. Поэтому и теорию типов (общую) я не воспринимаю как нечто «хаскельное», используют грамматики, могут и использовать любые другие формальные построения, в том числе теорию типов, если это понадобится. Большинство разработчиков реализаций никак не использую разные там теориях типов (видел, кстати, пост WHN примерно на эту тему - о алгебраических типах с TI применительно к CL). Вот CL это даже не столько (не только) язык, который мог бы быть и получше, сколько рантайм с определёнными свойствами, которые позволяют делать довольно полезные трюки.

Кто-нибудь видел операционную семантику Хаскеля?

Я не видел.

Хорошо, я буду на примерах.

Пример это «открой такой-то проект, посмотри такой-то макрос в таком-то файле». Мне ведь вобщем-то всё равно - просто я привык, что макрос это source to source преобразование не делающее больше ничего больше (всё делает тот код, который генерируется), а когда вы говорите что это нечто большее я, естественно, настаиваю на обратном. Вот gensym можно считать чем-то таким специфичным что есть на стадии раскрытия макросов, но оно вовсе не противоречит рассмотрению макросов как source to source функций, которые использует в своей работе macroexpand.

Вы же сами только что говорили, что макрос - это и есть обычная «нормальная» функция?

Которую использует macroexpand до этапа генерации кода (в compile-time). В runtime непосредственно работают обычные методы и функции (вы конечно можете запустить снова compile цикл в рантайм, или вручную взять макрос как функцию, но так делают довольно редко).

У CL рантайм = контекст экспанда, в CL вообще есть только один контекст, который всегда и отовсюду доступен.

Чё-то не очень вяжется с CLHS.

(defmacro yoba () (setq *param* ...)) и (defmacro yoba () `(setq *param* ...)) это в CL _одно и то же_

CL-USER> (defmacro foo1 () (setq *param1* t))

; in: LAMBDA NIL
;     (SETQ *PARAM1* T)
; 
; caught WARNING:
;   undefined variable: *PARAM1*
; 
; compilation unit finished
;   Undefined variable:
;     *PARAM1*
;   caught 1 WARNING condition
FOO1
CL-USER> (defmacro foo2 () `(setq *param2* t))
FOO2
CL-USER> (macroexpand-1 '(foo1))
T
T
CL-USER> *param1*
T
CL-USER> (macroexpand-1 '(foo2))
(SETQ *PARAM2* T)
T
CL-USER> *param2*
; Evaluation aborted on #<UNBOUND-VARIABLE *PARAM2* {24BBDF91}>.

Я предлагаю такое определение - форма f является «макросом с сайдэффектами», если сайдэффект имеет (compile 'f). Согласны?

Нет - если сайд эффект имеет (macroexpand-1 '(f ...)). Я об этом уже говорил в предыдущих постах. Это вы начали спорить с тем, что макрос это не source to source, или не вы?

Кстати,

yoba

Так вот оно что :)

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

>в CL никаких «стадий» нету.

http://www.lispworks.com/documentation/HyperSpec/Body/s_eval_w.htm#eval-when

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


ортогональные понятия

то, что стадии могут «переплетаться» не отменяет их существования

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

> У CL рантайм = контекст экспанда, в CL вообще есть только

один контекст, который всегда и отовсюду доступен.


Не смог распарсить. Как это вообще понимать? А как же let и progv?

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

> то, что стадии могут «переплетаться» не отменяет их существования

Они не переплетаются. Их НЕТ. Почитайте спеки, на которые сами дали линк.

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

> Не смог распарсить. Как это вообще понимать? А как же let и progv?

А при чем тут let и progv? Речь шла именно о различных контекстах для «стадий» исполнения. У CL один единственный контекст на все стадии, то есть если некая переменная доступна - она одинаково доступна и во время исполнения и вовремя компиляции и во время чтения - когда угодно.

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

> Речь шла именно о различных контекстах для «стадий» исполнения.

Это что за терминология такая вообще?

У CL один единственный контекст на все стадии, то есть если некая

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


и вовремя компиляции и во время чтения - когда угодно.



Я запутался о чём вообще речь. И зачем вообще об этом речь.

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