Готовы ли make файлы Тьюринга?
В последнее время на работе я делал перевод с Makefiles на альтернативную систему сборки. Я видел в некоторых местах довольно волосатый код Make, используя функциональные карты, фильтры и конструкции foreach. Это меня удивило, так как я считаю, что сценарии сборки должны быть как можно более декларативными.
Во всяком случае, это заставило меня задуматься: есть ли язык Makefile (скажем, последний GNU делает конкретным)? Тьюринг завершен?
Ответы
Ответ 1
Да, см. this. Как только у вас есть лямбда, все это спустится вниз.
Вот plagiarized Пример Fibonacci
Этого должно быть достаточно, чтобы создать основу для большей общности (мне нужно вернуться к работе, или я буду играть больше.)
dec = $(patsubst .%,%,$1)
not = $(if $1,,.)
lteq = $(if $1,$(if $(findstring $1,$2),.,),.)
gteq = $(if $2,$(if $(findstring $2,$1),.,),.)
eq = $(and $(call lteq,$1,$2),$(call gteq,$1,$2))
lt = $(and $(call lteq,$1,$2),$(call not,$(call gteq,$1,$2)))
add = $1$2
sub = $(if $(call not,$2),$1,$(call sub,$(call dec,$1),$(call dec,$2)))
mul = $(if $(call not,$2),$2,$(call add,$1,$(call mul,$1,$(call dec,$2))))
fibo = $(if $(call lt,$1,..),$1,$(call add,$(call fibo,$(call dec,$1)),$(call fibo,$(call sub,$1,..))))
fact = $(if $(call lt,$1,..),.,$(call mul,$1,$(call fact,$(call dec,$1))))
numeral = $(words $(subst .,. ,$1))
go = $(or $(info $(call numeral,$(call mul,$1,$1)) $(call numeral,$(call fibo,$1)) $(call numeral,$(call fact,$1)) ),$(call go,.$1))
_ := $(call go,)
Это отображает квадраты, числа фибоначчи и факториалы. По-видимому, существует 16-разрядный предел размера числа. Облом.
Ответ 2
Теперь для отрицательного ответа:
GNU активно блокирует некоторые механизмы для создания рекурсии:
1) Рекурсивно расширенные переменные
не являются рекурсивными в смысле "рекурсивной функции": они не могут быть определены в терминах самих себя:
Actually make detects the infinite loop and reports an error.
(Я не вижу, как их можно было бы использовать на практике, кстати.)
2) Цепочка правил
не может быть рекурсивным:
No single implicit rule can appear more than once in a chain. (...)
This constraint has the added benefit of preventing any infinite loop
in the search for an implicit rule chain.
(я потерял много времени на это, отлаживая свои Make файлы - в дополнение ко всем остальным, что затрудняет работу с make файлами.)
P.S. для недавнего проекта я написал патч для GNU make 3.82, который удаляет это ограничение с помощью новой опции -M (см. обсуждение). Это отлично работает для меня.