Greetings,

I'm considering submitting a proposal for a language change, and would like
some informal feedback on the idea before engaging the formal process.  The
idea being proposed here is intended to improve type safety by removing the
need for some error-prone type casting.  It is a backward compatible change.

Consider a body of code that works with people and events.  Both are
identified with integer IDs; in order to prevent them being used in the
wrong contexts, they are given specific integer types:
type EventID int
type PersonID int
Assume also that people have lists of events they attend:
type Person struct {
Events []EventID
}
The code maintains slices of each type:
var events []*Event
var people []*Person
When indexing into those slices, one can use the appropriate ID type:
var eventID EventID = 3
println(events[eventID])
However, iterating over these slices requires casting in the current Go
specification:
for eventID := range events {
// eventID here has type int, not type EventID
person.Events = append(person.Events, eventID) // compile error, wrong type
person.Events = append(person.Events, EventID(eventID)) // cast required
}
In cases where the event ID needs to be used inside the loop, it has lost
its type safety.  It has to be casted back to the type it is supposed to
have.  And that casting is error-prone; I could easily cast it to PersonID
by mistake.  This seems to be a noteworthy gap in type safety.

My proposal is to allow this construction:
var eventID EventID
for eventID = range events {
// eventID here has type EventID
person.Events = append(person.Events, eventID) // accepted by compiler
}
Phrased more formally: a slice range operator can be assigned to a variable
of any integer-derived type, not just "int".  If this were done,
error-prone casting could be avoided.

Admittedly, there is still room for error here, since it would be possible
to write
var eventID PersonID
for eventID = range events {
// eventID here has the wrong type PersonID
person.Events = append(person.Events, eventID) // compile error, wrong type
}
However, this error seems far less likely that a mistaken cast.  And since
there's no expectation that casts should be needed, the compiler error
would cause greater scrutiny leading to fixing the real problem.  (In any
case, I don't wish to propose the (much larger and more impactful) change
of having slices with typed indices.)

I believe this proposal would significantly improve type safety in programs
that work with multiple integer-derived types (such as most anything
working with a relational database that prefers integer primary keys).  I
also believe it is backward compatible since it does not change the
semantic of any existing code; it just adds a semantic to code that
currently would not compile.

I solicit the community's feedback.  Should this proposal be formally
submitted?

Regards,
Steve

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAAnpqKHS%3D2z0ZbNVSrULXLLGz%3DhAqpmrsLieciFu8L6%3DAn%3DLHA%40mail.gmail.com.

Reply via email to