ducttape
ducttape copied to clipboard
Allow variable references inside branch grafts
It would be nice if the following were allowed:
global {
test_references=(DataSet: a=foo b=bar c=baz)
}
task report
:: data_set=(DataSet: a b c)
:: files=${test_references}[DataSet: ${data_set}]
{
echo ${files}
}
I agree it would be nice. However, this would be rather difficult to implement as stated.
What's easy: Allow grafting restricted to literal parameters. Feel free to go ahead and add this to the syntax. It can be added with little pain.
What's hard: Allow grafting a branch that is itself based on a branch point. The current implementation compiles a HyperDAG from the syntax file as a first step and branch grafts must be annotated as literals on hyperedges (actually, they're annotated on each component incoming edge of each hyperedge). To allow these grafts to depend on branch points breaks a lot of assumptions.
We might be able to split this up into 2 issues.
Could you please clarify your comment by posting minimal tape file examples of what should and should not be allowed wrt this issue?
Assuming the following global block is always defined:
global {
test_references=(DataSet: a=foo b=bar c=baz)
}
- Allowed under the "easy" proposal:
task report
:: data_set="a" # The param data_set is a literal
:: files=${test_references}[DataSet: ${data_set}]
{
echo ${files}
}
- Allowed under the "easy" proposal:
global {
lit="a"
}
task report
:: data_set=$lit # The param data_set resolves to a literal
:: files=${test_references}[DataSet: ${data_set}]
{
echo ${files}
}
- Not allowed under the "easy" proposal:
global {
lit="a"
}
task report
:: data_set=(DataSet: a=foo b=bar c=baz) # The param data_set is a branch point (or it resolves to a branch point)
:: files=${test_references}[DataSet: ${data_set}]
{
echo ${files}
}
Most of the restrictions should be implemented in the StaticChecker rather than the parser.
One more note, in @dowobeha's original example, the grafting is actually a no-op and could be implemented as:
global {
test_references=(DataSet: a=foo b=bar c=baz)
}
task report
:: data_set=(DataSet: a b c)
:: files=${test_references}
{
echo ${files}
}
However, there are of course use cases where grafts that include variables would be useful.
Implementing this completely would requite abandoning literal grafts in the SpecGroup and instead using a ResolveableGraft that reveals what branches it wants to graft only once it is told what the current realization is.