Allow relaxed type casting on more general assignments?

103 views
Skip to first unread message

Mike Schinkel

unread,
Jan 14, 2025, 7:20:07 PMJan 14
to GoLang Nuts Mailing List
Hi all,

I have been wondering about the following for quite a while.  

In Go when assigning or passing values we all know we need to type-cast between two values whose types are derived from the same base type, and I assume most (all?) of us view that as good software engineering.  For example:

type Name string
type Code string 

var name Name  = "Hello"
var code Code  = Code(strings.ToLower(string(name)))

However, we do not have to cast in some cases, and AFAIK no one sees this as a negative e.g.:

fmt.Printf("%s: %s\n", name, code)

Given this I am now pondering why it would not be possible and acceptable it Go could allow relaxing of the need to type cast — on an opt-in basis — when going from a derived time to its base type?

For example, if `~` allowed us to opt-in to relaxed type casting and the signature in the standard library was `strings.ToLower(s ~name)` then we could drop the need to cast with `string(name)` for the prior case, like so:

var name Name  = "Hello"
// var code Code  = Code(strings.ToLower(string(name))) ==> the current requirement
var code Code  = Code(strings.ToLower(name))

The reason I am asking for this is that I really like to define derived types for scalar types to allow for more type safety in my programs. But doing that in many cases results in a lot of added complexity when I have to constant case back to the derived types when using generic function, especially for functions in the standard library.  And most teams I have worked on have pushed back on using types in this way because they would rather have the simplicity of not having to constantly cast types instead of the type safety provided by having bespoke types for each different type of values stored in a built-in type.

Is there a reason I am missing why it would be problematic if Go allowed developers to relax the need for type casting when going from a more specific type to a more general type? Os is there some way in which this might cause backward compatibility issues that I am not seeing?

To be clear — if you are just scanning this email before replying — I am only suggesting that type relaxation is opt-in for type declarations so it would not change the behavior of any of your existing bespoke code. However, I am hoping as part of such a change that the standard library functions could be updated to opt-in where applicable, as that is where I would see the biggest benefit.

-Mike

P.S. I created a simple example showing a use-case how such relaxation might be used:

https://go.dev/play/p/yllJ0CNZaAI

Ian Lance Taylor

unread,
Jan 14, 2025, 8:07:36 PMJan 14
to Mike Schinkel, GoLang Nuts Mailing List
On Tue, Jan 14, 2025 at 4:19 PM Mike Schinkel <mi...@newclarity.net> wrote:
>
> Given this I am now pondering why it would not be possible and acceptable it Go could allow relaxing of the need to type cast — on an opt-in basis — when going from a derived time to its base type?

There is a related discussion in https://go.dev/issue/71183.

it's worth noting that you can already in part do what you want, by
using generics.

func ToLower[S ~string](s S) S { ... }

Ian

Mike Schinkel

unread,
Jan 14, 2025, 11:11:12 PMJan 14
to Ian Lance Taylor, GoLang Nuts Mailing List
On Jan 14, 2025, at 8:06 PM, Ian Lance Taylor <ia...@golang.org> wrote:

On Tue, Jan 14, 2025 at 4:19 PM Mike Schinkel <mi...@newclarity.net> wrote:

Given this I am now pondering why it would not be possible and acceptable it Go could allow relaxing of the need to type cast — on an opt-in basis — when going from a derived time to its base type?

There is a related discussion in https://go.dev/issue/71183.

Thank you.

OTOH, it appears Rob Pike has shut it down.   Do you think his objections apply to my scalar type use-case? AFAICT they do not.

Reading through https://go.dev/issue/71183 it appears the entire discussion is really related to slices and not so much about scalar types for which I do not think any of the objections mentioned would actually apply for the use-case I asked about. What I asked about would not cause a value to have two different types, it would just automatically "down" cast on assignment. Also I am not suggesting something like `float64` => `float32`, only for automatic down-casting of a type to a type it is derived from.

Given that, it seems maybe I need to create my own proposal to ensure the type relaxing for non-slices does not get thrown out with the legitimate objections for doing the same for slices?

it's worth noting that you can already in part do what you want, by
using generics.

func ToLower[S ~string](s S) S { ... }

BTW, not really.  That wouldn't give me what I really want, and would also not work for methods on types.

What I REALLY want is to be able to call the standard library funcs that work on strings without having to typecast back to string   (small wins, ya know.) Being able to do the same with my own funcs is only a secondary want. :-)

-Mike
P.S. If I instead asked that all funcs in the standard library accepting strings be converted to use that generic signature, I assume that would be a non-starter for performance reasons, right?

Ian Lance Taylor

unread,
Jan 15, 2025, 12:06:05 AMJan 15
to Mike Schinkel, GoLang Nuts Mailing List
On Tue, Jan 14, 2025 at 8:10 PM Mike Schinkel <mi...@newclarity.net> wrote:
>
> P.S. If I instead asked that all funcs in the standard library accepting strings be converted to use that generic signature, I assume that would be a non-starter for performance reasons, right?

We couldn't change the standard library functions because it would
break compatibility. But I don't think there would be any performance
considerations.

Ian

Mike Schinkel

unread,
Jan 15, 2025, 2:34:27 AMJan 15
to Ian Lance Taylor, GoLang Nuts Mailing List
When you say compatibility, what would be a use-case where existing code would break? Something related to using reflection that expect the exact signature?

-Mike

Dan Kortschak

unread,
Jan 15, 2025, 2:39:22 AMJan 15
to golan...@googlegroups.com
On Wed, 2025-01-15 at 02:33 -0500, Mike Schinkel wrote:
> When you say compatibility, what would be a use-case where existing
> code would break?  Something related to using reflection that expect
> the exact signature?

For example https://go.dev/play/p/MLT3byjtGRJ

Mike Schinkel

unread,
Jan 15, 2025, 2:46:05 AMJan 15
to Dan Kortschak, GoLang Nuts Mailing List
Thank you.

So it seems the issue is the need to instantiate generic functions vs. a type compatibility issue if type casts to derived-from types could be automatic for those same functions.

-Mike
Reply all
Reply to author
Forward
0 new messages