Обновить

Комментарии 27

А может это любовь?

имхо навязывание новых, ненужных стандартов по силам только монополистам вроде microsoft и apple, а просто так это пустая затея

Промахнулся с веткой.
А может это любовь?

НЛО прилетело и опубликовало эту надпись здесь

Не вопрос. Меня тоже все устраивает. Даже более того - я вижу пути развития положительных качеств Elixir.

НЛО прилетело и опубликовало эту надпись здесь

#реализация макроса 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, насколько от сюда можно судить.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации