
Комментарии 27
А может это любовь?
имхо навязывание новых, ненужных стандартов по силам только монополистам вроде microsoft и apple, а просто так это пустая затея
#реализация макроса while в технике концевой рекурсии
defmodule Loop do
defmacro while(expression, do: block) do
quote do
loop(unquote(expression), unquote(block))
end
end
defmacro fun_block(block) do
quote do: unquote(block)
end
def loop(expression, block) do
try do
if expression do
fun_block(block)
else
Loop.break
end
catch
:break -> :ok
end
loop(expression, block)
end
def break, do: throw :break
end
На мой инженерный взгляд формальная ошибка в фразе:
• The first element is an atom denoting the function call, or another tuple, representing a nested node in the AST.
Ну не может в первом элементе содержаться "another tuple, representing a nested node in the AST."
По вашей просьбе запустил ещё раз. Подождал пять минут. Процесс действительно упал:-(
Буду думать и анализировать.
К сожалению, ваш пример не понял. Зато нашёл на stack overflow разбор родственного примера. https://translated.turbopages.org/proxy_u/en-ru.ru.89c95398-6766b1dc-f0097d79-74722d776562/https/stackoverflow.com/questions/60151752/recursive-macro-elixir
Там рекомендация очень выразительная:
суть в том, чтобы подумать, что вы делаете, чтобы избежать вызова макроса внутри
quote do [....] end.
У меня в макросе как раз опосредованный вызов макроса в блоке quote do [....] end.
Из объяснения я понял, что это ведет к бесконечному циклу на этапе компиляции. Это так?
Еще интересно, что в Scheme такой вызов макроса в макросе допускается?!
Если вызов макроса внутри quote do [....] endне возможен, то и рекурсия в макросе невозможна.
Я правильно понял?
Да сможет оно всё, заграбастать свой
pidчерез вызовself/0
Это понятно, но в конце концов нет тела процесса - нет и дела, т.е. некому обрабатывать проверку... Process.alive?(pid)
Не спорю. Я вообще не спорю, а выражаю частное мнение, дополняющее мнение Dave Thomas
Получается, что я переадресовываю к Thomas.
Очень хорошо. Но тезис:
применяйте макросы Elixir там, где необходимо производить вычисления в процессе компиляции.
остается правильным.
проверка выполняется не процессом, а виртуальной машиной
Если честно, то этого я не понял. Виртуальная машина просто "молотилка", которая обрабатывает код процесса, а условие проверки заключено в коде.
От дискуссии "разрядилась" батарейка у мышки. Пошёл покупать новую. Вернусь, выложу вызывающий код оболочки. Как говорится "Не переключайтесь."
Я вернулся:-)
Мне кажется дело в спецификациях на макрос, которые есть у Криса.
Одна проектная:
while Process.alive?(pid) do...
Другая, полученная в результате:
defmacro while(expression, do: block) do...
Т.е. в конечном итоге pid процесса остался снаружи. И это корректная модель. Если процесс уже отработал по каким-то причинам, то посылка сообщения в "некуда" возвратит «холостой» вызов оператора send. И пользователь может понять, что процесса уже нет.
Так я понял Криса.
Мы проектируем макрос
while/2. Он принимаетexpression(в данном случае —Process.alive?(pid) — и do-блок
Обязательно попробую, когда перезагружусь в рабочую OS. Формально должно сработать. Крис в качестве expression прямолинейно передавал константу true. Да, это должно работать!
Но смысл? Интроспекция какая-то!
И тем не менее, если процесс по каким-то причинам упал, то и развернутогоexpression в коде уже нет, и самого кода нет.
в первом элементе первой туплы — тупла
Буду изучать.
Сижу, разбираю ваш код. Было бы полезно посмотреть код функции five_factorial_compile_time...
Попытался дизассемблировать модуль Test при помощи :compile.disassemble("Test.beam")
В результате получил сообщение, что отсутствует функция disassemble. Копать дальше не стал, т.к. реальный интерес направлен на содержание функции five_factorial_compile_time
Интерес к дизассемблированию не праздный: у меня не падает процесс:
iex(19)> :calendar.local_time();
{{2024, 12, 24}, {12, 21, 10}}
iex(20)> send pid, :hello
:hello
iex(21)> :calendar.local_time();
{{2024, 12, 24}, {12, 39, 15}}
iex(22)> Process.alive? pid
true
Все по-честному. Что было перед этим, не знаю.
И почитайте, наконец, про синтакс маркдауна
Чувствую, что давно пора, да руки не доходят. Извините.
пока не увижу, откуда взялась локальная переменная
pid
Все по Крису:
iex>
pid = spawn fn ->
while true do
receive do
:stop ->
IO.puts "Stopping..."
break
message ->
IO.puts "Got #{inspect message}"
end end end
С новым годом, учитель, и пожелание всех благ!
Хочу повиниться. Процесс рекурсивного макроса действительно падал, но я обнаружил это после.
Process.alive? pid
показывал true, а
посылка сообщений уходили в некуда.
Почему так, я не разобрался.
Наверное, вы имели в виду, не популизм, а популизаторство. Это архиважно!
У меня сложилось впечатление, что вы лично знакомы с Дейвом, Брюсом (Tate?) и Крисом.
Если это так, то передайте привет из страны Севера.
Еще здесь очень ценят вклад Криса в real time в Elixir, насколько от сюда можно судить.
Критика чистого макроса