Skip to content

Commit

Permalink
add generic type matching
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Sep 23, 2023
1 parent 531cf0f commit dde8737
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
9 changes: 7 additions & 2 deletions src/common-concepts/control-flow/match-statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Default
```

### Type Matching
The `any` data type may contain any data and you may want to execute different algorithms based on this data, in which case type matching is useful. You can also determine types of trait's data. Type matching is easy. Just use the keyword `type` and then use the data type in case to match.
The `any` or `trait` data type may contain any data and you may want to execute different algorithms based on this data, in which case type matching is useful. You can also determine types of trait's data. Type matching is easy. Just use the keyword `type` and then use the data type in case to match.

For example:
```jule
Expand All @@ -117,4 +117,9 @@ fn main() {
outln("other")
}
}
```
```

### Generic Matching

Type-Math is also used to map generics.
See the [Generic Type Matching](/types/generics#generic-type-matching) section for more information about this.
15 changes: 11 additions & 4 deletions src/std/jule-sema.md
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,12 @@ struct Match {
default: &Case
}
```
Match-Case.
Match-Case.

**Methods:**

`fn is_generic_type_match(self): bool`\
Reports whether match is type-match for generic type.

---

Expand Down Expand Up @@ -1123,6 +1128,7 @@ struct TypeAlias {
public: bool
cpp_linked: bool
used: bool
generic: bool
token: Token
ident: str
kind: &TypeSymbol
Expand All @@ -1140,9 +1146,10 @@ Type alias.

```jule
struct TypeKind {
cpp_ident: str
variadic: bool
kind: Kind
cpp_ident: str
generic: bool
variadic: bool
kind: Kind
}
```
Type alias.
Expand Down
35 changes: 31 additions & 4 deletions src/types/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ Generic types are also assumed to be local in-scope type aliases. Therefore, the
Generics are never supports shadowing.
:::

## Runtime Cost of Generics
Short answer: Generics hasn't any cost for runtime.

The cost of generics is that they typically add potentially additional time to compile times. When generics are evaluated as compile-time, there may be a cost, but the same is not true for runtime. Jule's generics cost nothing to runtime, you have no losses.

The generated code is created specifically for each generic combination, and each combination uses its own unique algorithms. There is no difference in runtime. Each generic type is determined at compile time and is compiled accordingly preserving the static type. So even if you use generic types at runtime, you get the performance of no-generic definitions at no cost.

## Generics for Functions
::: warning
Genericed functions never can used as anonymous function or type annotation.
Expand Down Expand Up @@ -80,9 +87,29 @@ fn main() {
```
Dynamic generic annotation is used in the above example. Generic types are automatically detected from the data type of argument by compiler.

## Runtime Cost of Generics
Short answer: Generics hasn't any cost for runtime.
## Generic Type Matching

The cost of generics is that they typically add potentially additional time to compile times. When generics are evaluated as compile-time, there may be a cost, but the same is not true for runtime. Jule's generics cost nothing to runtime, you have no losses.
[Type-match](/common-concepts/control-flow/match-statement#type-matching) statements can be used to implement different algorithms for generic types. There is no runtime cost, matches are checked at compile time. Cases that do not match are not checked, so you will not encounter problems such as type mismatches and you will prevent semantic analysis errors for mismatched cases.

The generated code is created specifically for each generic combination, and each combination uses its own unique algorithms. There is no difference in runtime. Each generic type is determined at compile time and is compiled accordingly preserving the static type. So even if you use generic types at runtime, you get the performance of no-generic definitions at no cost.
For example:

```jule
fn println[T](x: T) {
match type T {
| str: out("Str: ")
| bool: out("Bool: ")
| f64: out("64-bit float: ")
| int: out("Integer: ")
|: out("Unkown: ")
}
outln(x)
}
fn main() {
println(10)
println(true)
println(20.5)
println("MyString")
println(any(nil))
}
```

0 comments on commit dde8737

Please sign in to comment.