[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.