buvinghausen/TaskTupleAwaiter

[Optional] Add T4/other mechanism for generating the source code for more generic types

taori opened this issue · 14 comments

taori commented

I can't really think of a use case where i had to do more than 5 things in parallel, but there might be others who desire to do more things in parallel.

I imagine someone would truely be sad if he can't use this library because he has to do 11 parallel requests.

(Given that i am unaware of whether there is a c# restriction on how many generic constraints can be specified)

jnm2 commented

I am getting close to 10 in one place, but that's the only one over 3 that I remember right now. The BCL usually stops at 16. (E.g. Action overloads.) C# doesn't spec a limit and Roslyn's limit is stupendously high IIRC.

Would T4 actually save time in the long run? We would have to generate tests for new arities too. My gut says that simply following the existing pattern to add more (upon request) would be most efficient.

Is It Worth the Time? XKCD comic

taori commented

@jnm2 I see what you're getting at. I'm not particularly concerned with the effort it would take to add arities, but rather just dislike anything of such an extended file size which has to be maintained manually.

If you dislike the thought of investing the time in writing a T4 template for this i 100% agree - Thinking back the last time i had work at a task, which would have been simple if code generation were easy (for not so straight forward requirements), was when i found out roslyn was about to be released, resulting in me tossing away 4 days of attempts and being done within hours.

If you would consider a PR for this, i would be willing to provide one.

Fitting meme

jnm2 commented

We sure appreciate that, but I'm unsure. It's not a straightforward win; maintaining the T4 templates once you're done will increase the complexity cost for anything we do going forward, as well as raising the threshold for potential contributors. On the other hand, maybe it'll be simpler to understand and maintain than I'm guessing based on my previous T4 work.

@buvinghausen, what do you think you'd like to do?

taori commented

We sure appreciate that, but I'm unsure. It's not a straightforward win; maintaining the T4 templates once you're done will increase the complexity cost for anything we do going forward, as well as raising the threshold for potential contributors. On the other hand, maybe it'll be simpler to understand and maintain than I'm guessing based on my previous T4 work.

@buvinghausen, what do you think you'd like to do?

Actually my plan would be creating a roslyn based CLI solution. That way, whenever someone needs a specific arity, he can just generate it on demand.

T4 templates have poor readability compared to code generated using roslyn imo.

jnm2 commented

Would tests still be added manually for higher arities?

taori commented

Would tests still be added manually for higher arities?

After looking at the tests now i'd have to say that specifying a constant for the maximum count of arities, or getting that information from reflection, would work for quite a bunch of tests. However there are quite a bunch of tests, which verify the syntax as well. For those the tests would either have to be generated too, or one would have to rely on there not being an actual difference between everything working the same for arrity 11, as it would for arity 10 -

That would be less than ideal obviously. Especially with the level of detail that went into writing all those tests, it would get ugly when generating testing code.

jnm2 commented

So if the test code wouldn't be autogenerated, several manual steps will always apply if we add new arities- something which I could see us doing once or maybe twice, ever. The tool would be cool, but would we actually use it at that point, or would we do the same thing with the production code that we would be doing anyway with the test code? I.e., manually extrapolating?

taori commented

That's what i am thinking too. As you pointed out to to begin with there were few cases where your desire required more than 10 arities anyways.

Having a tool generate the source would be rather simple, because it's just the same thing over and over and over with multiple extrapolations, but generating the plentitude of tests which were created would make it a nightmare to keep tests updated, because there are multiple ones which take arity into consideration.

jnm2 commented

I'm now sitting at an arity of ten in this one project, so I vote we do bump it up to 16 a la https://github.com/dotnet/corefx/blob/v2.2.1/src/System.Runtime/src/System/Action.cs. Would you be interested in being involved in that, however you choose to obtain the source?

taori commented

I'm now sitting at an arity of ten in this one project, so I vote we do bump it up to 16 a la https://github.com/dotnet/corefx/blob/v2.2.1/src/System.Runtime/src/System/Action.cs. Would you be interested in being involved in that, however you choose to obtain the source?

If that was directed at me, the answer is yes.

jnm2 commented

@taori It was! That's great! I'll leave it with you to PR? Let me know if you need anything. If you end up wanting to contribute a Roslyn generator, that's the kind of project I'd normally put in a /tools repository folder or similar.

taori commented

@jnm2 Is what you are recommending a structure like:
buvinghausen/TaskTupleAwaiter/tools/Tools.sln
buvinghausen/TaskTupleAwaiter/tools/generator.console/generator.console.csproj? I'll set it up like that then. Also i would probably do a SyntaxFactory.Parse based approach. I would use roslyn to verify that the generated source is valid and compiles. Doing it with pure syntax tree is doable, but it would make the mainteneance unnecessarily difficult. Sounds good or any further comments?

jnm2 commented

Sounds good to me! I usually avoid putting Console in project names because it gets irritating to qualify the name of the Console class.

taori commented

@jnm2 alright. Generator.CLI it is.