4 ms·
Pretty sure that some usage patterns of polymorphic types can not be completely monomorphized. Here's example in Golang: package main import (
by Joker_vD 4y ago
Pretty sure that some usage patterns of polymorphic types can not be completely monomorphized. Here's example in Golang:
package main
import (
"fmt"
)
type wrapper[T any] struct {
Value T
}
func (w wrapper[T]) String() string {
return fmt.Sprintf("{%v}", w.Value)
}
func stringWrapped[T any](n int, v T) string {
if n == 0 {
return fmt.Sprintf("%v", v)
}
return stringWrapped(n-1, wrapper[T]{Value: v})
}
func main() {
n := 0
fmt.Scanf("%d", &n)
result := stringWrapped(n, "test")
fmt.Println(result)
}
Go refuses to compile because it can't possibly generate all instances of wrapper[T] that this program may use: wrapper[string], wrapper[wrapper[string]], wrapper[wrapper[wrapper[string]]], etc.
- estebank 4y agoRust will complain about a recursion limit being reached during instantiation[1]. The solution in Rust is to use &dyn Trait or Box<dyn Trait> instead.[2] [1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7bfb188bc741d69ee2bd5ce68982c049 https://play.rust-lang.org/?version=stable&mode=debug&editio... [2]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b5a03fafeda6ec964c47aca41ccd997e https://play.rust-lang.org/?version=stable&mode=debug&editio... ^ This blows the stack because it keeps calling itself with no break condition, but shows how the type system accepted the code.
- gpderetta 4y agoI think this is called polymorphic recursion in Haskell circles. In C++ you can monomorphize as long as you can somehow prove the recursion terminates at compile time (for example by threading a static recursion counter).