🚧 Generics proposal#34
Conversation
| * global value and alias declarations are immutable and must be initialized. What if we could override them? if so, this is a simple mechanism for module specialization. | ||
| What if we also could override struct and functions declarations? In fact, all declarations? | ||
|
|
||
| It proposes two extensions: [**Generic Declarations**](#generic-declarations) and [**Generic Modules**](#generic-modules) (+ optional [**Function-as-Type**](#function-as-type) [**Module-as-Type**](#module-as-type)). |
There was a problem hiding this comment.
I could write a github issue on the desire for generic declarations from my earlier work in stoneberry if that's still useful.
There was a problem hiding this comment.
in any case, I'll try to do a mock rewrite of one of the stoneberry files with the generic syntax.
|
|
||
| See [the map reduce example](#map-reduce). | ||
|
|
||
| ## Generic Modules |
There was a problem hiding this comment.
Is it clear that generic modules are the best way forward to add ergonmics to generic elements? If so, let's discuss here, if it's more debatable, perhaps we should split this part into a separate issue/PR.
|
|
||
| We introduce a `@generic` attribute to define the generic parameters and constraints. | ||
| ```rs | ||
| @generic(Num: AbstractFloat, T: MyStruct, N: u32) |
There was a problem hiding this comment.
Putting the generic paramaters between the fn name and the runtime parameters list is more traditional, no?
e.g. fn foo<A: MyStruct, B>(a:A, b:B) { }
Why not do that? Are you trying to minimize the new syntax? Does it create a parsing ambiguity?
| ```rs | ||
| let res: array<f32, 10> = my_fn<f32, SomeStruct, 10>(3.5f, struct_inst); | ||
|
|
||
| @generic(T: AbstractFloat) |
There was a problem hiding this comment.
AbstractFloat and AbstractInt are kinda wordy. How 'bout f64 and i64?
|
|
||
| * WGSL *already* has support for parametric types and functions, they are called [type-generators](https://www.w3.org/TR/WGSL/#type-generator) and [function overloads](https://www.w3.org/TR/WGSL/#builtin-functions). It even has some syntax for them. | ||
| The issue is, they are not allowed to be declared in user code. This proposal changes this. | ||
| * A *module* is a collection of functions, structs and associated types that share a semantic. Turns out, a WGSL file is just that. This proposal introduces *implicit modules* as files. |
There was a problem hiding this comment.
The glossary defined Module as a single WESL file. Are implicit modules something different?
(guessing it's just distinguishing vs the discussions of explicit namespaces within a file.)
| This allows extending structs by narrowing down a member type, or by adding new members. | ||
| * (optional) function signature `F1` is a subtype of function signature `F2` if, | ||
| * `F1` and `F2` have the same number of formal parameters, | ||
| * the `i`th formal parameter of `F1` is a subtype of the `i`th formal parameter of `F2` (parameter covariance), |
There was a problem hiding this comment.
Aren't function parameters parameters typically contravariant?
| They are orthogonal but they share the concepts of [*Type Hierarchy*](formalism-type-hierarchy) and [*Generic Type*](#formalism-generic-type) formalized below. | ||
| We could support only one of the two and achieve the same expressivity AFAIK. But not the same ergonomics. | ||
|
|
||
| ## Formalism: Type Hierarchy |
There was a problem hiding this comment.
For most people (not all!) I think it'd read better with an example or two before we dig into the formalism.
| return binOpMax<E>(elems[0], elems[1]); // generic value applied at call site | ||
| } | ||
| ``` | ||
| Type checking does not have to be enforced by the linker, especially for runtime linking where we care about performance. |
| ``` | ||
| Type checking does not have to be enforced by the linker, especially for runtime linking where we care about performance. | ||
| All of this proposal (except module-as-types) can be implemented with simple substitution. | ||
| A compile-time linker or a IDE linter/langserver should implement type checking. Basically what Typescript does. |
There was a problem hiding this comment.
I think I know where you're going, but it's a little confusing because of course the TypeScript compiler does do type checking. (I think you mean that typical web development these days combines a fast transpiler that does no typechecking with a language server that does type checking)
A proposal for function and modules generics using respectively the
@genericand@overrideattributes.Still rough around the edges, need more thought. Ideas and comments are welcome.