Replies: 13 comments
-
Related but different proposal with different use cases #78 #685 'fixed-size-buffers' |
Beta Was this translation helpful? Give feedback.
-
See also #357 |
Beta Was this translation helpful? Give feedback.
-
@orthoxerox I think there is whole bag full of generics or in general type system enhancement proposals like #339 Higher Kinded Polymorphism cited in #357 and it looks like type system supported by CLI and C#/F# needs urgently major upgrade. |
Beta Was this translation helpful? Give feedback.
-
@4creators generics are not templates. They are working over Type calculus and it's an awful idea to emulate it via generics. What's wrong with: public unsafe struct Tensor<T> where T : struct
{
public fixed T[] Foo;
public Tensor(int n) => Foo = new T[n];
} except that currently it's not possible to do in C#? This proposition makes much more sense to me. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@Pzixel Absolutely agree that generics are not templates but IMO generics provide for managed languages significantly better abstraction for programming with type parametrization than C++ with templates. I know MSDN entry you linked to and I have consulted it before writing proposal but I do not agree that my proposal violates C# generics principles. It is not supported now but for users it should be very intuitive. What is overlooked in my proposal is the usage of const keyword which results in several consequences: (i) constexpr generic parameter has to be defined at compile time, (ii) fixed size buffers do not have
The main difference is that size of Firstly, fixed array does not contain size information and since runtime would have no knowledge about array size it would prevent effective bounds checks (if needed) unless it would be an ordinary managed array containing information on it's size. Arrays in type system have a layout containing field with a pointer to buffer and an integer field containing buffer size. This syntax change would destroy one of the most important parts of the proposal from my perspective - predefined size and layout of structure in memory. This would prevent using it to represent i.e. pixels of an image in packed pixel format - there are dozens of pixel formats used in imaging. Secondly, by using constructor parameter intializing size of the fixed array during type initialization at runtime we loose all advantages brought by statically typed language - compile time control of syntactic type correctness and as a result we end up with Thirdly, it is impossible to construct As a counter example let's have a look at following code snippet - I want to multiply 11 x 7 Matrix by 7 element Tensor what would give as a result 7 element Tensor (Matrix is as above but with corresponding to Your example modifications): public unsafe struct Tensor<T> where T : struct
{
public fixed T[] Foo;
public Tensor(int n) => Foo = new T[n];
public Tensor<T>[] Multiply(Matrix<T, Tensor<T>> matrix, Tensor<T> tensor);
}
public static class Matrix
{
public static Tensor<T> Multiply<T>(Matrix<T, Tensor<T>>, Tensor<T>) { ... }
}
Matrix<double, Tensor<double>> m = new Matrix<double, Tensor<double>>( 5, new Tensor<double>[][]{ new Tensor<double>[]{ ........... }, ..... new Tensor<double>[] { ................ } });
Tensor<double> t = new Tensor<double>(3); // we pass t through several calls until
for (int i = 0; i < t.Length; i++) // We do not have Length property on Foo unless it's standard managed array what is incompatible with proposal
t.Foo[i] = Math.Sin((double)i);
var result = Matrix.Multiply<double>(m, t); // error at runtime - AccessViolationException and corrupted memory @HaloFour my proposal explicitly eliminates possibility of having dynamic arrays as non type parameter constraint is that it has to be AFAIR there is nothing in current generics implementation that prevents extending it with |
Beta Was this translation helpful? Give feedback.
-
I want this feature for this library: https://github.com/ufcpp/BitFields/ |
Beta Was this translation helpful? Give feedback.
-
@4creators I see usecases for this feature however I think if we add such a possibility we can free the jinn. I guess we'd better have some another mechanism beside generics. I don't mind as user if array has length 4 or 5, but it would be completely different type and I have to specify that method receives Tensor<3>. We gen completely different design if we change a common array with a fixed one, and it's not only related to implementation. but to its interface too. I'm also not sure it will work fine with current |
Beta Was this translation helpful? Give feedback.
-
Above referenced API Proposal would directly benefit from generics enhancements described here see https://github.com/dotnet/corefx/issues/22940 |
Beta Was this translation helpful? Give feedback.
-
Would this feature allow strings as generic parameters? E.g.
|
Beta Was this translation helpful? Give feedback.
-
This is extremely interesting and could well serve as the basis for implementing this much more easily: We could create what we want "out of the box" using this feature if it gets traction. Incidentally I wonder if the "const" is redundant here in that the language would no doubt insist it be a compile time constant anyway? |
Beta Was this translation helpful? Give feedback.
-
FYI I have implemented a prototype of this feature for CoreCLR, you can already try out const generics today: dotnet/runtime#89636 |
Beta Was this translation helpful? Give feedback.
-
Hey everyone, I've implemented a full working coreclr runtime and C# compiler to support this feature. And I've successfully made an SDK for it, so you can build and run your code directly just use Visual Studio or Visual Studio Code. Please do follow the README.txt. My implementation supports the below things:
UPDATE on 2023/9/1: Fix a bug that can cause stackoverflow while you using generics on const type parameter. |
Beta Was this translation helpful? Give feedback.
-
Const blittable generic parameter syntax
Rationale
C# generics do not allow for non-type generic parameters, such as
class C<int i>{}
.Ability to parametrize generic type with non-type parameters provides additional expressiveness in language which allows to support large class of new and useful code patterns. Constraining non-type generic parameters to
constexpr blittable values
(see issue #206) simplifies significantly implementation and provides most desired feature - predefined, controllable memory layout.Combining above syntax with proposal from issue #653 allows for even more expressive syntax
Currently attempt to implement
struct Tensor<T, const int N>
forT : (byte, sbyte, short, ushort, int, uint, long, ulong, float, double)
and for dimensionsN: (1 ... 128)
would result in creation of 1280 Tensor related structure types.Situation gets even worse if we try to work with matrices composed of
struct Tensor<T, const int N>
If we want to work with matrices with dimensions
Y: (1 ... 128)
andX: (1 ... 128)
we would need to create 163 840 Matrix related types for all underlying numeric types.What we want to do next is of course creation of some implementations of useful algorithms which would operate on Tensor and Matrix derived structures. Let's assume we want to have all basic operations ....
All above examples could be simplified to implementation which does not require fixed arrays but still relies on constant dimensions. This problem was already encountered in the framework and runtime implementation where .NET Framework developers decided to provide optimized implementation for 2 out of 163 840 Matrix types
System.Numerics.Matrix3
andSystem.Numerics.Matrix4
which are hand crafted specializations ofMatrix<Tensor<float, 3>, 3>
andMatrix<Tensor<float, 4>, 4>
. How aboutMatrix<Tensor<double, 3>, 3>
andMatrix<Tensor<double, 4>, 4>
?Alternatives
In
System.Drawing
assembly there are matrices used for large set of transformations based on System.Drawing.Imaging.ColorMatrix. Constructor for ColorMatrix and initialization code example from MSDN is as follows:The consequence of the above implementation is that there are no compile time checks for the correctness of ColorMatrix initialization. One can pass float[7][5] array as well. Errors will be detected only at run time. This situation leads to possibility of introducing the whole class of simple or subtle bugs into implementations based on ColorMatrix pattern which can be detected only at run time with additional run time checks which have to be implemented and executed. This lowers both developer productivity and run time performance.
Positives
Proposed feature eliminates whole class of bugs and run time errors increasing at the same time developer productivity by enhancing language expressiveness.
Negatives
May require significant work to be implemented.
Beta Was this translation helpful? Give feedback.
All reactions