KEMBAR78
const parameters feature proposal - based on Issue #744 and Design Review: Hardware Intrinsics for Intel by 4creators · Pull Request #886 · dotnet/csharplang · GitHub
Skip to content

Conversation

@4creators
Copy link

@4creators 4creators commented Sep 7, 2017

Description of the proposal contains specifics about implementation details and formal syntax
proposed to support Constant Parameters C# feature. It is accompanied by early Roslyn prototype which
supports const parameters declaration, invocation of methods with constant arguments with value
expressed as constant expression, overload resolution with support for 'const' parameters modifiers.

Still no support for assembly code generation as there is no final decision how to represent 'const' parameters
at the CLI level. Roslyn Constant Parameter feature has conditional support. Very limited tests.

…w: Hardware Intrinsics for Intel

Description of the proposal contains specifics about implementation details and formal syntax
proposed to support Constant Parameters feature. It is accompanied by early prototype which
supports const parameters declaration, invocation of methods with constant arguments with value
expressed as constant expression, overload resolution with support for 'const' parameters modifiers.

Still no support for code generation as there is no final decision how to represent 'const' parameters
at the CLI level. No working implementation for Roslyn Constant Parameter feature conditional support,
however, everything is stubbed to support it. Very limited tests.
@4creators 4creators changed the title [WIP] Proposal for Constant Parameters based in Issue #744 and Design Review: Hardware Intrinsics for Intel [WIP] Proposal for Constant Parameters based on Issue #744 and Design Review: Hardware Intrinsics for Intel Sep 7, 2017
@4creators 4creators changed the title [WIP] Proposal for Constant Parameters based on Issue #744 and Design Review: Hardware Intrinsics for Intel const parameters feature proposal - based on Issue #744 and Design Review: Hardware Intrinsics for Intel Sep 12, 2017
@4creators
Copy link
Author

I expect that PR may be to some extend incomplete (sorry for that), however, wanted to help with speeding up hardware SIMD intrinsics feature implementation.

PTAL
/cc @MadsTorgersen @jaredpar @terrajobst @fiigii @mellinoe @tannergooding

@4creators
Copy link
Author

Thanks for comments. Fixed errors and style.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Dec 10, 2017

Dumb question: The motivating scenario for this language feature seems to be:

allowing to enforce passing of compile time constant values as a method, delegate, constructor, lambda expression, anonymous and local method parameters.

It's unclear to me why this needs language support. Wouldn't it be far quicker and easier to just make the api like this:

public static Vector256<float> Shuffle(
    Vector256<float> value, Vector256<float> right, [Const] byte control);

And then have an analyzer that validates that the code compiled against it passes a constant? Such a solution could be provided today, and would satisfy the use case well without needing any language changes and without gating the features on the compiler then implementing those changes.

--

Actually, i can see you wrote something about this in the doc:

There are no reasonably fully functional alternatives which would be based on compile time type safety. It is possible to implement similar functionality using attributes and compiler / analyzer support but with inferior user experiance - errors during method invocation will be raised due to the fact that parameter is marked with attribute. As a consequence there will be no overload resolution due to parameters difference being an attribute or overload resolution would be based on parameters attribute differences.

But this seems really tenuous. First:

but with inferior user experiance - errors during method invocation will be raised due to the fact that parameter is marked with attribute.

Why is this an inferior user experience? It addresses the core need, and does so in a way that is natural and familiar to C# devs.

As a consequence there will be no overload resolution due to parameters difference being an attribute or overload resolution would be based on parameters attribute differences.

This seems like a good thing. Would we expect to have methods like "Foo(int i)" and "Foo(const int i)"? That seems like something that would be dramatically easy to get wrong. Someone could easily forget to put the "const" at the callsite and would then call the former method instead of the latter. It seems like you would not want overloading based on const/non-constness. And, as such, an attribute is utterly fine for this sort of thing.

There are no reasonably fully functional alternative

This just seems wrong. There's a totally reasonable alternative on the table. It's cheap and simple and can be done today.

--

In other words, even if i posit that the attribute+analyzer isn't perfect and isn't as awesome as having a keyword, it's still literally thousands of times cheaper to get up and running today. It also seems to provide a more than good enough solution for the problem space. You could write this up and have it shipped in a day and give more than good enough results for this use case. Whereas trying to make a language change here could take years, and still never get done. Even if you did, years from now, get it through the language, it would only be marginally better at best than the solution that exists today :)

@4creators
Copy link
Author

4creators commented Dec 10, 2017

Would we expect to have methods like "Foo(int i)" and "Foo(const int i)"?

Yes. There are quite a bit of SIMD instructions taking 2, 3, 4 arguments which have versions supporting both immediate or compile time constants arguments and variables as arguments of given type. They are exposed as C++ intrinsics by all major compilers with overload resolution support like:

int Foo(int var1, int var2);
int Foo(int var1, const int var2);

The difference between C++ and C# would be that C++ const modifier does not support enforcing compile time constants while C# const would.

Someone could easily forget to put the "const" at the callsite and would then call the former method instead of the latter

In C++ world it is up to the developer to write correct code and the same could be expected of C# developers I think.

Whereas trying to make a language change here could take years, and still never get done.

I agree that doing it via attribute - analyzer is faster decision wise, however, implementation of const parameter prototype took me around 10 hours of work where I could not be described as a person knowledgeable with Roslyn code base. I bet it is very cheap to implement and from my perspective as a language and programming purist far superior to attribute - analyzer. The reason for this being that attribute was not designed to be used as a way to impose syntactic rules in a language. If it is used that way I do think it violates the very principles of good programming language design.

@CyrusNajmabadi
Copy link
Member

Yes. There are quite a bit of SIMD instructions taking 2, 3, 4 arguments which have versions supporting both immediate or compile time constants arguments and variables as arguments of given type. They are exposed as C++ intrinsics by all major compilers with overload resolution support like:

Having FooImmediate and Foo seems like a totally reasonable approach.

In C++ world it is up to the developer to write correct code and the same could be expected of C# developers I think.

If this is the case... then why need the language change in the first place? :)

If you can just depend on C# developers writing correct code, you don't need a language feature that enforces that they're doing things correctly.

I bet it is very cheap to implement and from my perspective as a language and programming purist far superior to attribute - analyzer. The reason for this being that attribute was not designed to be used as a way to impose syntactic rules in a language

Actually, they were. This is the entire idea behind analyzers. Note: you wouldn't even need the attribute. You could just say: Here is an analyzer that just knows about this vector instruction API. When it sees you using it improperly, it lets you know.

This was a core goal behind analyzers. They were so people could write an API and supply an extra set of rules about how that API should be used properly. It was entirely so API usage could be checked without needing extra language/compiler rules.

That's entirely what's happening here. You have an API you want called in very specific ways. And you want warnings/errors if the user doesn't call it in that way. That's 100% in the realm of analyzers.

@CyrusNajmabadi
Copy link
Member

I bet it is very cheap to implement

Being cheap to implement is definitely good. But it's not a reason to do something. It needs to be the rigth choice for the language. We make language changes considering a multitude of factors, including (but not limited to):

  1. the existing ways to do something are non-existent or insufficient. (not the case here).
  2. the marginal benefit is large. (not the case here IMO).
  3. the feature will be used by a large subset of our ecosystem. def not the case here.

etc. etc.

Another way to think about it that your 10 hours multiple out by 100x when you consider needing to have the language design team design and consider all the implications here. When they have to make sure it works properly in all possible language/feature permutations. When the compiler team has to implement and verify across all the necessary permutations. Making sure the IDE works properly. Getting things doc'ed. Getting things spec'ed. etc. etc. And that's time that will be compared against the 'zero cost', supported and encouraged path of using analyzers.

--

and from my perspective as a language and programming purist far superior

That's not a good reason :) Making something 100x more costly for exceptionally marginal gain isn't good language design or engineering. Purism definitely falls way to pragmatism in how we do things.

@mikedn
Copy link

mikedn commented Dec 10, 2017

There are quite a bit of SIMD instructions taking 2, 3, 4 arguments which have versions supporting both immediate or compile time constants arguments and variables as arguments of given type.

Examples?

They are exposed as C++ intrinsics by all major compilers with overload resolution support like:

C++ doesn't support this kind of overloading. If there really intrinsics that do support this then that's really a special case, not something that the standard language supports.

The difference between C++ and C# would be that C++ const modifier does not support enforcing compile time constants while C# const would.

Not really. C++ compilers actually produce errors if you provide non-constants in such cases. Though not because the parameter is const but because compilers have special handling for intrinsics.

@tannergooding
Copy link
Member

I logged an issue against CoreFX (see https://github.com/dotnet/corefx/issues/26174) suggesting that a repo or project specifically for CoreFX related analyzers be created.

There is also a bit of sample code (more of a prototype really: https://github.com/dotnet/corefx/issues/26174#issuecomment-355476154) that shows how trivial it is to implement a diagnostic analyzer that enforces a given parameter is constant (adding an attribute and checking against that would make it even more simple).

@tannergooding
Copy link
Member

Closing this as proposals should not be checked-in until after a given feature is championed.

CC. @gafter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants