summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-08-28 22:26:50 -0700
committerGitHub <noreply@github.com>2024-08-28 22:26:50 -0700
commit69e0f878e02d61280110b379f9d346acde7575a8 (patch)
treeb8cfa4d5bba30e8f92e799f733c1caf2d72e5833 /docs
parentefda04f3cc784dde42bd15fd1d33edeea0f3cd92 (diff)
Update `IFunc` proposal to reflect its implementation. (#4950)
Diffstat (limited to 'docs')
-rw-r--r--docs/proposals/009-ifunc.md67
1 files changed, 38 insertions, 29 deletions
diff --git a/docs/proposals/009-ifunc.md b/docs/proposals/009-ifunc.md
index 646f5f55b..373e2dedc 100644
--- a/docs/proposals/009-ifunc.md
+++ b/docs/proposals/009-ifunc.md
@@ -10,9 +10,11 @@ Status
Author: Yong He
-Implementation: Planned.
+Status: Implemented.
-Reviewed by: N/A
+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
----------
@@ -57,49 +59,50 @@ eliminating the need for defining interfaces and wrapper types.
Proposed Approach
-----------------
-We propose `IFunc` and `IMutatingFunc` that is defined as follows:
-
+We should support overloading of `operator()`, and use the function call syntax to call the `operator()` member, similar to C++:
```
-// Function objects that does not have a mutating state.
-interface IFunc<TResult, each TParams>
+struct Functor
{
- TResult __call(expand each TParams params);
+ int operator()(float p) {}
}
-// Function objects with a mutating state.
-interface IMutatingFunc<TFunc, each TParams>
+void test()
{
- [mutating]
- TResult __call(expand each TParams params);
+ Functor f;
+ f(1.0f);
}
```
-Ordinary functions are treated as conforming to `IFunc` and `IMutatingFunc` automatically,
-so the following code is valid:
+We propose `IFunc`, `IMutatingFunc`, `IDifferentiableFunc` and `IDiffernetiableMutatingFunc` that is defined as follows:
```
-int countElement(int data[100], IFunc<bool, int> condition)
+// Function objects that does not have a mutating state.
+interface IMutatingFunc<TR, each TP>
{
- int count = 0;
- for (int i = 0; i < data.getCount(); i++)
- if (condition(data[i]))
- count++;
- return count;
+ [mutating]
+ TR operator()(expand each TP p);
}
-int myCondition(int x) { return x%2 == 0; } // select all even numbers.
+// Function objects with a mutating state.
+interface IFunc<TR, each TP> : IMutatingFunc<TR, expand each TP>
+{
+ TR operator()(expand each TP p);
+}
-void test()
+// Differentiable functions
+interface IDifferentiableMutatingFunc<TR : IDifferentiable, each TP : IDifferentiable> : IMutatingFunc<TR, expand each TP>
{
- int data[100] = ...;
- int count = countElement(data, myCondition);
+ [Differentiable]
+ [mutating]
+ TR operator()(expand each TP p);
}
-```
-An ordinary function or static function with type `(T0, T1, ... Tn)->TR` is coerceable to `IFunc<TIR, TI0, TI1, ... TIn>` if
-`TI0, TI1, ... TIn` are coerceable to `T0, T1, ... Tn` and `TR` is coerceable to `TIR`.
-To achieve this, the compiler will synthesize a wrapper struct type conforms to the `IFunc` interface, and calls the original function
-in its `__call` method.
+interface IDifferentiableFunc<TR : IDifferentiable, each TP : IDifferentiable> : IFunc<TR, expand each TP>, IDifferentiableMutatingFunc<TR, expand each TP>
+{
+ [Differentiable]
+ TR operator()(expand each TP p);
+}
+```
The `IMutatingFunc` interface is for defining functors that has a mutable state. The following example demonstrates its use:
@@ -115,7 +118,7 @@ struct CounterFunc : IMutatingFunc<void, int>
int count;
[mutating]
- void __call(int data)
+ void operator()(int data)
{
if (data % 2 == 0)
count++;
@@ -131,3 +134,9 @@ void test()
printf("%d", f.count);
}
```
+
+# Coercion of ordinary functions
+
+Eventually, we should allow ordinary functions to be automatically coerceable to `IFunc` interfaces. But this is scoped out
+for the initial `IFunc` work, because we believe the implementation can be simpler if we support lambda function first, then
+implement ordinary function coercion as a special case of lambda expressions. \ No newline at end of file