Jouke, You need a recursive let if you want to be able to define inner functions, like a helper function.
On Mon, Dec 30, 2024, 5:21 AM Jouke Witteveen <j.wittev...@gmail.com> wrote: > 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 >