Since the beginning, VL offers a way to build generic patches.
While in the very beginning we tried to get away without the need to flag patches, we at some time decided that the user should flag those generic patches:
generic checkbox on operation definition regions:
generic checkbox on data type definitions and process definitions:
The idea here is that providing the intent whether this shall be a generic patch, should help the system and the user. It allows the system to deliver better feedback - via typing hints or errors and unused nodes and links and alike - depending on whether this shall be a generic patch or not.
VL wants to be the language that makes working with generics a breeze. And we can deliver to quite some degree.
The type inference is able to infer type parameters and replace them with fitting concrete types that respect all constraints arising
from links in the patch
type annotations inside the patch
type parameter constraints stemming from used nodes and types
We respect
subtype constraints T where T: ISupertype
new - type must have a default constructor,
struct - type must be a value type,
class - type must be a reference type
immutable - type must be a record type
in any combination when in the search for a fitting type.
Note: This is happening in nongeneric patches as well. You can use generic nodes and types inside nongeneric patches. The system just needs to find the right concrete type argument for those type parameters.
In generic patches we also try to find an answer to the question of whether it is better to substitute a type parameter of a used generic node or type with
a fitting concrete type (respecting all constraints)
OR
a newly declared type parameter (optionally with some type constraints attached) - and thus actually and finally making this node or type definition a generic one.
But to be honest this isn't a question that always comes with a straight-forward answer.
Often the user doesn't have to help the system further, but
Issue A
there are cases where the user needs to put quite some work into helping the type inference by
adding type annotations on pads and pins
artificially constraining type parameters with nodes like ConstrainTypes
in order to get rid of superfluous type parameters.
Issue B
Also when defining a generic type with more than one type parameter we run into a problem:
If we don't have a way of specifying the order of the type parameters on our very own type definition, how should we be able to make sense of a type annotation like this: MyType<Float32, Boolen>? What does that mean? We weren't in control when defining the type parameters on our type, we weren't able to define the order of those type parameters. So can we trust that those automatically created type parameters will always stay in that order? Will this type application MyType<Float32, Boolen> always mean the same, or is this unstable?
Summary
We identified a language flaw when defining generic types with more than one type parameter.
We identified a need for some more explicit control over type parameters when defining any generic node or type.
Brainstorming about generics in VL in general
Since the beginning, VL offers a way to build generic patches.
While in the very beginning we tried to get away without the need to flag patches, we at some time decided that the user should flag those generic patches:
generic checkbox on
operation definition regions
:generic checkbox on
data type definitions
andprocess definitions
:The idea here is that providing the intent whether this shall be a generic patch, should help the system and the user. It allows the system to deliver better feedback - via typing hints or errors and unused nodes and links and alike - depending on whether this shall be a generic patch or not.
VL wants to be the language that makes working with generics a breeze. And we can deliver to quite some degree.
The type inference is able to infer type parameters and replace them with fitting concrete types that respect all constraints arising
We respect
T where T: ISupertype
new
- type must have a default constructor,struct
- type must be a value type,class
- type must be a reference typeimmutable
- type must be a record typein any combination when in the search for a fitting type.
Note: This is happening in nongeneric patches as well. You can use generic nodes and types inside nongeneric patches. The system just needs to find the right
concrete type
argument for those type parameters.In generic patches we also try to find an answer to the question of whether it is better to substitute a type parameter of a used generic node or type with
OR
But to be honest this isn't a question that always comes with a straight-forward answer.
Often the user doesn't have to help the system further, but
Issue A
there are cases where the user needs to put quite some work into helping the type inference by
ConstrainTypes
in order to get rid of superfluous type parameters.
Issue B
Also when defining a generic type with more than one type parameter we run into a problem: If we don't have a way of specifying the order of the type parameters on our very own type definition, how should we be able to make sense of a type annotation like this:
MyType<Float32, Boolen>
? What does that mean? We weren't in control when defining the type parameters on our type, we weren't able to define the order of those type parameters. So can we trust that those automatically created type parameters will always stay in that order? Will this type applicationMyType<Float32, Boolen>
always mean the same, or is this unstable?Summary
We identified a language flaw when defining generic types with more than one type parameter. We identified a need for some more explicit control over type parameters when defining any generic node or type.