Skip to content

proposal: spec: add builtin func 'is[T any](any) bool' #65846

@adonovan

Description

@adonovan

Go Programming Experience

Experienced

Other Languages Experience

many

Related Idea

  • Has this idea, or one like it, been proposed before?
  • Does this affect error handling?
  • Is this about generics?
  • Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit

Has this idea, or one like it, been proposed before?

Not to my knowledge.

Does this affect error handling?

No.

Is this about generics?

Indirectly.

Proposal

I propose that we add an intrinsic is function, equivalent to this Go declaration:

// Is[T] reports whether the type assertion x.(T) would succeed.
func is[T any](x any) bool {
     _, ok := x.(T)
    return ok
}

This operator makes it possible to test the type of an interface without breaking out of expression mode, which is especially helpful when writing code that makes heavy use of sum types, such as syntax trees, types, XML documents, and so on.

if len(calleeDecl.Body.List) == 1 &&
                is[*ast.ReturnStmt](calleeDecl.Body.List[0]) &&
                len(calleeDecl.Body.List[0].(*ast.ReturnStmt).Results) > 0 { // not a bare return

Of course, one can write this function in Go or import it from a package, but like min and max it is ubiquitous and fundamental, and warrants a short name.

Language Spec Changes

The universe scope defines an is function, whose declaration is equivalent to the Go code shown above.

Informal Change

The is operator performs a test of an interface's dynamic type.

Is this change backward compatible?

Yes.

Orthogonality: How does this change interact or overlap with existing features?

Very orthogonal.

Would this change make Go easier or harder to learn, and why?

No net change. Harder, because one more thing to learn; easier, because less frustrating breaking out of expression mode.

Cost Description

No response

Changes to Go ToolChain

local changes to cmd/compile, go/types, a few others

Performance Costs

none

Prototype

See above.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions