简体   繁体   中英

GNUmake: how to write a true lambda

The following is my take on a so-so emulation of a lambda expression in GNUmake :

space := $(strip) $(strip)
comma := ,

# convert a space-separated list in $1 into a comma-separated list:
list2param = $(subst $(space),$(comma),$(strip $1))

# param $1 = quoted GUNmake expression
# param $2 = parameters to the expression as space-separated list
lambda = $(eval _lambda=$1)$(eval _lambda:=$$(call _lambda,$(call list2param,$2)))$(_lambda)

Example:

$(info $(call lambda,$$1 .. $$2 .. $$3,foo bar baz))

Output:

foo .. bar .. baz

But this is less than satisfying, as I have to use a variable "_lambda" behind the curtain and the mechanism isn't really like lambda as the evaluation isn't separated from the definition. Is there a clean, direct way to implement a lambda? Or is there already some mechanism implemented which my blind procedural programming eyes didn't catch?

As in any primitive substitution language, you defer evaluation by quoting. The example below looks horrible and doesn't let you nest lambdas, but otherwise works:

define lambda
$(eval lambda-f=$1)lambda-f
endef

$(foreach n,1 2 3,$(call $(call lambda,$$(info $$(shell seq -s ' ' $$1))),$n))

Some readability can be (arguably) regained by amending the syntax like this:

define lambda
$(eval lambda-f=$(subst ^,$$,$1))lambda-f
endef

$(foreach n,1 2 3,$(call $(call lambda,^(info ^(shell seq -s ' ' ^1))),$n))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM