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

Reply via email to