SP #009 - IFunc interface ============== Now that we have variadic generics in the language following [SP #007], we should now be able to define a builtin `IFunc` interface that represent things that can be called with the `()` operator. This will allow users to write generic functions that takes a callback object and adopt more functional programming idioms. Status ------ Author: Yong He Status: Implemented. Implementation: [PR 4905](https://github.com/shader-slang/slang/pull/4905) [PR 4926](https://github.com/shader-slang/slang/pull/4926) Reviewed by: Kai Zhang, Jay Kwak Background ---------- Callback is an idiom that frequently show up in complex codebases. Currently, Slang users can implement this idiom with interfaces: ``` interface ICondition { bool test(int x); } int countElement(int data[100], ICondition condition) { int count = 0; for (int i = 0; i < data.getCount(); i++) if (condition.test(data[i])) count++; return count; } int myCondition(int x) { return x%2 == 0; } // select all even numbers. struct MyConditionWrapper : ICondition { bool test(int x) { return myCondition(x); } }; void test() { int data[100] = ...; int count = countElement(data, MyConditionWrapper()); } ``` As can be seen, this is a lot of boilerplate. With a builtin `IFunc` interface, we can allow the compiler to automatically make ordinary functions conform to the interface, eliminating the need for defining interfaces and wrapper types. Proposed Approach ----------------- We should support overloading of `operator()`, and use the function call syntax to call the `operator()` member, similar to C++: ``` struct Functor { int operator()(float p) {} } void test() { Functor f; f(1.0f); } ``` We propose `IFunc`, `IMutatingFunc`, `IDifferentiableFunc` and `IDiffernetiableMutatingFunc` that is defined as follows: ``` // Function objects that does not have a mutating state. interface IMutatingFunc