help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FEATURE:? binding variables to prerequisites


From: Kaz Kylheku (gmake)
Subject: Re: FEATURE:? binding variables to prerequisites
Date: Fri, 22 Jan 2021 17:04:41 -0800
User-agent: Roundcube Webmail/0.9.2

On 2021-01-22 13:18, Cook, Malcolm wrote:
Hi Paul et. al.,

When a rule has multiple prerequisites I sometimes use make variables
to refer to them positionally, like this:

^1=$(word 1,$^)
^2=$(word 2,$^)
^3=$(word 3,$^)
^2..=$(wordlist 2,$(words $^),$^)
^3..=$(wordlist 3,$(words $^),$^)

%.foo: %.bar %.baz %.bat1 %.bat2 %.bat3
        process --baz ${^2}--bar ${^1} --bat ${^3..} > $@

What do you think of such syntactic sugar?

Arguments in macros are already $(1), $(2). (But those were used, it would cause "optical difficulties" in rules generated by macros.)

Speaking of macros, the above can be achieved very verbosely now using call:

prereq = $(word $(1),$^)

$(call prereq 3)  # -> $(word 3,$^)

Firstly, it would be nice if macros with arguments could be invoked without the clunky $(call).

I propose this syntax:
For instance, the syntax

  $(prereq)     # straight old substitution with no args
  $(prereq 3)   # == $(call prereq,3): substitution with $(1) = 3.

Additional arguments use commas

  $(foo 1,2,3)  # $(call foo,1,2,3)

Now, if we define a one-letter macro, like $(p 3), we have good density.

A further abbreviation facility could then perhaps be developed which binds dispatch characters to macros so that $(^3) can become $(prereq 3). That only saves one
space over $(p 3) though.

Of course, without $(call ...), macros now clash in the namespace of predefined operators.
If someone does this:

  word = whatever

$(word 1,abc def) # this is the built-in, not a call of the above word

Makefiles then run the risk of breaking because they
used some word that is later claimed as a new built-in by
a new version of GNU Make. Some namespace rules could be documented.
For instance, no built-ins start with a capital letter currently
and future ones likely won't also, so that seems like a safe space
for defining macros. Such names clash with the reserved environment
space in POSIX, though.

Another idea might be to have some shorthand for $(call ...) like
say $[abc x,y,z,...] <--> $(call abc,x,y,z,...).

That's eerily like what I did in TXR Lisp.

1> '(dwim f x y z)
[f x y z]
2> (car '[f x y z])
dwim
3> (cdr '[f x y z])
(f x y z)
4>


dwim is a special dispatching operator whose name you almost never
directly mention in any conceivable code due to the [ ] shorthand.
It calls functions, accesses hashes, indexes into sequences like
lists vectors and strings and also allows for LIsp-1 style
programming in a dialect that is fundamentally Lisp-2 (separate
variable and function namespace).

E.g. (mapcar cons '(1 2 3) '(a b c)) won't work, because there
is no cons variable, but [mapcar cons '(1 2 3) '(a b c)]
will, because of a name lookup semantics alteration imposed by
the dwim operator.

But I digress.

GNU Make is almost like Lisp-2 because when you create a macro, you're
essentially storing a function definition into a variable,
and that is not in the right namespace to be invoked directly;
a calling operator is required.

The [] notation works well with indices. In the Make example we would
end up with  $[p 0] $[p 1] which looks like indexing into an
array p of prerequisites.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]