(let ((v (make-array (+ 4 (length d))))
(i -1))
(setf (aref v (incf i)) a)
(setf (aref v (incf i)) b)
(setf (aref v (incf i)) c)
(loop for x across d do (setf (aref v (incf i)) x))
(setf (aref v (incf i)) e)
v)
Да ладно, есть, например paredit: иногда наоборот при редактировании «традиционного» кода быстрее «оскобить» выражения -> paredit-raise-sexp / transpose-sexp.
В CL есть сахар для конструирования списков в компайл-тайме
Мне не нравится именно сама необходимость в явном виде заворачивать конструкцию в квотирование. В идеале, хотелось бы, чтобы backquote не было, а функция его выполнялась.
Можно навелосипедить собственную обертку и вынести её на самый верхний уровень программы, чтобы не мозолила глаза. Получится как-то так:
В результате работы макроса use-outer-macro, везде, где в глубинах «всего остального кода» встечаются unbox или another-unbox, их внешний список будет завернут в соответственно do-unbox и do-another-unbox. Т.е. (some-function a b c (unbox v) d) превращается после подстановки в (do-unbox (some-function a b c (unbox v) d)). Ну а потом получившееся уже обрабатывается как нормальная лисп-программа.
Правда если в пределах одного списка обнаружится больше одного «внешнего» макроса, получится ересь.
В общем, хотелось бы как-то эту задачу красиво решить, но именно красиво не получается.
Унарная псевдооперация * подставляет содержимое аргумента-контейнера в рантайме
А что в руби уже можно подставлять что-то в компайл-тайме? Я так понимаю, что эта «псевдо» операция просто разворачивается в вызов метода, который делает сплайсинг. Ну такой вот малополезный синтаксис.
В идеале, хотелось бы, чтобы backquote не было, а функция его выполнялась.
И как вы предлагаете различать, что выполнять при компиляции, а что в рантайме?
А что в руби уже можно подставлять что-то в компайл-тайме?
Нет, но не все ж знакомы с семантикой Ruby. Поэтому уточнил.
Я так понимаю, что эта «псевдо» операция просто разворачивается в вызов метода, который делает сплайсинг. Ну такой вот малополезный синтаксис.
Да, но разворачивается она на уровень выше по синтаксическому дереву, чем дано в исходнике. Я хочу проэмулировать это поведение: макрос указан во внутреннем списке, а макроподстановка выполняется во внешнем списке.
> В идеале, хотелось бы, чтобы backquote не было, а функция его выполнялась. И как вы предлагаете различать, что выполнять при компиляции, а что в рантайме?
В данном случае нам надо не «вообще» от него отказаться, а чтобы квотирование «магически» проявлялось вокруг списка, если в одном из его дочерних списков пристутствует указанный (псевдо)макрос.
Да, это всё из разряда «хочу странного». :} Но хочу.
а чтобы квотирование «магически» проявлялось вокруг списка, если в одном из его дочерних списков пристутствует указанный (псевдо)макрос.
Ну, можно навернуть свой кастомный ридер с магией. Но лично я предпочел бы прямо вызывать функцию сплайcинга, хоть в лиспе, хоть в руби - так и понятнее и гибче.
Чего «лол»-то, ооп-костыль же. Это ведь даже не синтаксический сахар, а _специальная конструкция для передачи «self» в качестве первого аргумента для :empty или я ошибаюсь?
Макросы в lisp-подобных языках дают возможность похлёбывать мамкин борщок, клепая очередной никому не нужный кластер метапарадигм, а также обсуждать на форумах анафорические лямбды и смотреть на всех, как на говно.
На это моих познаниний еще хватает. Был вопрос про амперсанд.
аргумент как блок
Это уже интереснее, в («a»..«f»).map(&:upcase) -> («a»..«f»).map{|e| e.send :upcase} можно понимать как «удаление внешних скобок и раскрытие в блок?
А в f(...) как можно формализовать?
Мне не нравится именно сама необходимость в явном виде заворачивать конструкцию в квотирование.
Но в руби то ты в квотирование заворачиваешь вполне явно. Непонятно в чем проблема. Ну можешь #%app тогда перегрузить или скобки. Но зачем? Во всех ящыках используется явное
Квотирование и всех это устраивает.
Да, но разворачивается она на уровень выше по синтаксическому дереву, чем дано в исходнике
ЭТо с чего ты взял? В руби макрос - открывающая [, которая указывает, что гдето внутри формы можеь быть звездочка. Все в точности как с лисповыми ' и ,.
ЭТо с чего ты взял? В руби макрос - открывающая [, которая указывает, что гдето внутри формы можеь быть звездочка. Все в точности как с лисповыми ' и ,.
Ну как не при чем? Именно благодаря тому что перед звездочкой стоит [ эта звездочка интерпретируется как слайсинг. А в двух других приведенных тобой случаях она интерпретируется иначе. То есть [ перегружает значение звездочки внутри своей формы.
Для осоьо одаренных - та звездочка что в оп-посте вообще ее имеет смысла вне []. Так что если бы она интерпретировалась одинаково, то последние два примера были бы ошибкой. У splat есть 4 совершенно разных смысла и в каком именно смысле он используется - зависит от контекста. в квадратных скобках - слайсинг, в определении метода - аналог лиспового &rest, в вызове метода - apply, в присваивании - множественое присваивание. Соответственно и макроом будет не сама звездочка, а внешние задабщие конекст формы: квадратные скобки, определение/вызов метода, присваивание. Я полагал, что человек знающий руби, должен быть в курсе таки. очевидных вещей
Поэтому звездочка в [] имеет ровно тот же самый смысл, что и внутри круглых скобок при вызове любого другого метода. Потому что это засахаренный вызов метода, блеать.
И ровно то же самое относится и к присваиванию, потому что рубиевское присваивание a, b, c = *v в lisp-форме эквивалентно записи а ля (do-unbox (= '(a b c) (unbox(v)))) . Только с поправкой, что присваивание как прямой вызов метода нам из сорцов на руби не доступно.
а внешние задабщие конекст формы
Ага, а в примерах из стартового поста формы (do-unbox (function1 a b c (unbox v))), (do-unbox (function2 a b c (unbox v))), (do-unbox (function3 a b c (unbox v))) следовало бы считать построенными с использованием разных макросов, потому что после формирования списка аргументов каждый раз вызывается разная функция.
Включай мозги и учись правильно различать различные уровни абстракции, «знаток руби».
Что в лоб что по лбу. Еще раз, для совсем тупых - макрос это не звездочка, а обрамляющая форма, в которой эта звездочка используется. Если хочешь чтобы внутри аппикации можно было делать слайсинг аргументов - переопределяй макрос аппликации, если хочешь чтобы при определении ф-и можно было делать слайсинг аргументов - переопределяй дефайн, если хочешь при присваивании - переопределяй присваивание. Собственно первые два пункта в лиспе сделаны - rest-аргументы и apply+слайсинг в списках, ну а множественного присваивания какбы и нет. Именно такая семантика в руби, и другой она быть не может в принципе. Только в руби макросов нету, просто ы грамматике для соответствующих нетерминалов указанг, что внутри может быть звездочка.
Еще раз, для совсем тупых - макрос это не звездочка, а обрамляющая форма, в которой эта звездочка используется.
Еще раз для совсем тупых: в руби нет макросов, и все сабжевые фичи являются частью синтаксиса. Поэтому рассуждать на тему, что было бы если бы у бабушки был ..., можно сколько угодно.
Если хочешь чтобы внутри аппикации можно было делать слайсинг аргументов - переопределяй макрос аппликации, если хочешь чтобы при определении ф-и можно было делать слайсинг аргументов - переопределяй дефайн, если хочешь при присваивании - переопределяй присваивание
Задача стартового поста состояла в том, чтобы выполнять трансформацию AST на уровень выше вхождения в него соответствующего макроса. То, о чем ты пишешь, вообще к теме треда отношения не имеет, потому что является решением другой задачи. Для неисправимо тупых: синтаксис руби был приведен в качестве наглядного примера.
Разницу между задачами «делать слайсинг» и «вызвать произвольный макрос для внешней формы», надеюсь, твой слабый мозг осилит.
Задача стартового поста состояла в том, чтобы выполнять трансформацию AST на уровень выше вхождения в него соответствующего макроса.
Для начала надо как бы определиться с тем, осмысленно ли это преобразование. Выполнение преобразования на уровень или несколько уровней выше требует хотя бы построить это самое AST _полностью_. Вопрос: если рядом с макросом есть макрос (или вызов макрос находится внутри другого макроса):
(a
(b)
(macro-1)
(macro-2)
(macro-3
(c)
(macro-4)
(d)))
то какой макрос какое AST должен увидеть?
Я постулирую, что нельзя подобрать такой единый локально консистентный порядок раскрытия макросов, чтобы изменяемое дерево AST было подходящим для полезных практических макросов.
для макросов, видимо, да — но макросы это прошлый четвертьвек
а в практических задачах часто требуется сделать так, чтобы, так сказать, макросоподобное средство что-то добавило (или даже поменяло) рядом с собой, а не под собой
Ну это же ложь. Макросы как раз самая перспективная область исследований, и именно сейчас, когда все связанное с системами типов уже полностью изучено и признано неэффективным. Макросы же предлагают совершенно новые подходы.
а в практических задачах
ну так в практических задачах это и дедается безо всяких проблем точно также как в руби - внешняя форма переопределяет семантику внутренней.
Тл есть не ложь? Хоть один факт можешь в подтверждение предоставить?
краткий обзорчик этих исследований и полученных результатов можно?
Результаты - это повсеместно использование макросов и прочего метапрограммирования, когда язык это позволяет. Исследования в области теории типов ни одним подобным результатом похвастаться не могут.
Я и не противопоставлял. Система типов - это не более чем попытка ограниченного метапрограммирования, при расширении выразительности системы типов приходят к макросам (бестиповая лямбда с гигиеническими макросами - это по сути минимальное construction of calculus с подтипированием, типами являются алгоритмические подмножества термов, макросы - полиморфными функциями с ограниченной квантификацией), так что макросистема - это система типов сделанная правильно
Тл есть не ложь? Хоть один факт можешь в подтверждение предоставить?
я щас добрый, и мне лень тебя на место ставить любопытный, и вдруг ты все-таки обзорчик предоставишь? (не обязательно pdf)
Результаты - это повсеместно использование макросов и прочего метапрограммирования, когда язык это позволяет.
нет
ты не понимаешь, что такое результаты научных или околонаучных исследований
для шаблонов с++, скажем, это выработка понимания, что нужны концепты
для системы типов хаскеля — это, скажем, выработка понимания того, что все-таки нужны семейства типов (бугага, не прошло и 20 лет после появления шаблонов в плюсах, как они с помпой сделали что-то похожее)
з.ы. и еще я не считаю системы типов верхом совершенства, вот так
Да я просто пример привел, как самую непутевую часть CS. Полезные вещи тоже, конечно, делаются, но об этом почти никто не знает, зато о том что вышла книга по гомотопической теории типов уже каждая собака в курсе.
Система типов - это не более чем попытка ограниченного метапрограммирования
ты категорически неправ, осиль хотя бы первые 20 страниц TAPL
то, что метапрограммирование, скажем, в с++ прикручивают к системе типов — это не совсем правильно (хотя, конечно, «макросы» должны уметь оперировать с типами), и *точно* система типов делалась не под это
это не результаты, это игра в бирюльки. Я могу просто перечислить рандомный набор полезных для использования макросов фич, и сказать что пришло понимание, что они нужны, но банально смысла в этом не вижу.