enough-garden-22763
05/21/2021, 10:47 PMOutput<A>, Output<B>, Func<A,B,C>
and wanting to get Output<C>
is the least verbose option Output.Tuple(a,b).Apply(x => func(x.Item1, x.Item2)
and specifically are there reflection or codegen helpers I’m missing to generalize this on records to convert between records where properties are typed T1,..TN and records where properties are typed In/Output<T1>..In/Output<TN>
? Working on some codegen helpers here and my current attempt looks like this: https://gist.github.com/t0yv0/a9139fd04f28a5d4e8f1cf20909023ae#file-codegen-cs-L21worried-city-86458
05/22/2021, 5:48 AMpublic static Output<ListStorageAccountKeysResult> Apply(ListStorageAccountKeysApplyArgs args, InvokeOptions? options = null) =>
Output.Tuple(args.AccountName, args.Expand, args.ResourceGroupName)
.Apply(((string AccountName, string Expand, string ResourceGroupName)tuple) => InvokeAsync(
new ListStorageAccountKeysArgs
{
AccountName = tuple.AccountName,
Expand = tuple.Expand,
ResourceGroupName = tuple.ResourceGroupName
}, options));
tall-librarian-49374
05/22/2021, 6:57 AMTuple
is limited to 8 parameters.enough-garden-22763
05/24/2021, 1:38 PMworried-city-86458
05/27/2021, 5:54 AMpublic static Output<ListStorageAccountKeysResult> Apply(ListStorageAccountKeysApplyArgs args, InvokeOptions? options = null) =>
new { args.AccountName, args.Expand, args.ResourceGroupName }.ToOutput() // magic here
.Apply(anon => InvokeAsync(
new ListStorageAccountKeysArgs
{
AccountName = anon.AccountName,
Expand = anon.Expand,
ResourceGroupName = anon.ResourceGroupName
}, options));
enough-garden-22763
05/27/2021, 6:05 PMTuple
packed into max-8 trees ran the limit of C# refusing to do type inference on these (I miss F#). You can see the current candidate implementation here https://github.com/pulumi/pulumi/pull/7087/files#diff-009df8f241c8e473d30f34b62a89229ed7fbbc2b89f3e4404794184a1db06887worried-city-86458
05/27/2021, 7:23 PMOutput.All
with awkward indexing of the lifted result:
Output.All(args.A, args.B).Apply(array => array[0] ... array[1] etc)
with:
Output.Anon(new { args.A, args.B }).Apply(anon => anon.A ... anon.B etc)
which would need an output apply pipeline like:
Output.Anon(a').Apply(b')
where a' and b' are anonymous types and b' has the same shape (property names) as a' except all the types are the "lifted" types of a'enough-garden-22763
05/27/2021, 8:46 PMworried-city-86458
05/27/2021, 9:39 PMAre you thinking to generally improve experience for users that try to join a few outputs together?Yes! 😀 Both
Output.All
and Output.Tuple
are clumsy to use because you lose property name access on the way through.enough-garden-22763
05/27/2021, 9:43 PMOutput.Combine(v => v.Eval(x) + v.Eval(y))
interface IOutputEvaluator {
T Eval<T>(Output<T> output);
}
Output<T> Output.Combine<T>(f: Func<IOutputEvaluator,T>)
f
arg not as a real function but more as a “magic” function which only works for reduced instructions. The user is not allowed to branch on the results of outputs or conditionally evaluate an output. Since the implementation introspects f
by evaluating it several times.. Side-effects are also not allowed.worried-city-86458
05/27/2021, 10:13 PM