Compile-time control flow with type inference

75 views
Skip to first unread message

Mark Mavzon

unread,
Nov 5, 2024, 12:33:28 AMNov 5
to golang-nuts
Tried writing a poor man's union (sum) "type" using generic functions and recursion but found an issue. Here's the code:
type nothing any
type Or[V, R any] struct {
value any
rest any
}
func NewOr[V any]() Or[V, nothing] {
return Or[V, nothing]{nil, nil}
}
func TypeOr[V, W, R any](or Or[W, R]) Or[V, Or[W, R]] {
return Or[V, Or[W, R]]{nil, or}
}
type ErrorA struct {}
type ErrorB struct {}
type ErrorC struct {}

var UseCaseError = TypeOr[ErrorA](TypeOr[ErrorB](NewOr[ErrorC]()))

So far so good. If you copy and paste the above code into VSCode you can see a readable type in the tooltip for the UseCaseError variable.
To get the value from this variable we need a function like this:
func Get[V, W, R any](or Or[W, R]) (*V, bool) {
if value, ok := or.value.(V); ok {
return &value, true
}
        // Here the compiler should check whether the type parameter R
        // is actually a type Or[W1, R1].
        // If it is the compiler should infer W1, R1 and insert the code from the 1st branch.
        // Otherwise it should insert the code from the 2nd branch.
if_at_compile_time isOr := R.(Or[W1, R1 infer]); isOr {
            return Get[V](or.rest.(Or[W1, R1]))
} else {
    return (nil, false)
        }
}
Without compile-time check like this there's no way to break from the recursion inside a generic function (I think). But it looks like there's nothing like this in Go? Perhaps there should be?

Axel Wagner

unread,
Nov 5, 2024, 1:25:11 AMNov 5
to Mark Mavzon, golang-nuts
It's not clear to me, what W1 and R1 are in your example.

But FWIW, Go has no way to do compile-time meta programming and is unlikely to ever get one. It interacts too poorly with the goal of predictably fast compile times and the general safety assumptions of Go (you can run `go build` and be sure it can't do anything nefarious).

I also don't think this would be a compelling argument to add anything like it. The code you are trying to write seems very hard to understand and use. And too clever for its own good by orders of magnitude. Personally, I really don't want Go to enable something like that.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/3babbcdd-1692-4273-b699-8c39ace8c830n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages