Hi Pete, On Thu, Dec 26, 2024 at 7:44 AM Pete Dietl <petedi...@gmail.com> wrote: > I propose adding a "letrec" builtin to complement the "let" builtin. > The "let" builtin does not allow one to define inner functions or > mutually recursive definitions.
Can you maybe help me understand why this functionality would be desirable? Sure, recursively expanded variables with a limited scope could be a thing, but I fail to see what functionality they would offer. The way I see it, recursively expanded variables are mainly useful when you don't know all the values of the variables referenced, which is exactly not the case when you limit the scope. > Variable names and their values are provided pairwise. "Letrec" strips > any leading whitespace from the expansion of each variable name > argument. Your suggestion does not do any kind of multiple assignment (I modeled `let` a bit after `read`), so it does not need to have a variable number of arguments and could just be $(letrec NAME,MACRO,EXPRESSION) and, apart from nested bindings, the main use would be $(letrec NAME,MACRO,$(call NAME,PARAM)) which is equivalent to just MACRO with $1 replaced by PARAM. > Here is an example Makefile using the new function: > > print-var = $(info $$($1) = '$($(1))') > > $(letrec \ > a,foo, \ > b,bar, \ > c,$(call double,~hello~), \ > double,$(1)$(1), \ > $(call print-var,a) \ > $(call print-var,b) \ > $(call print-var,c) \ > $(info 2 x $$(a) = '$(call double,$(a))') \ > ) In your example, you don't need `letrec` for `a` or `b` and all I see is a roundabout way of writing $(foreach x,foo ~hello~,$(info $(x) $(x))) Regards, - Jouke