Skip to content

Instantly share code, notes, and snippets.

@robmccoll
Created April 3, 2020 19:23
Show Gist options
  • Save robmccoll/edbd0f80ea2c5d7851b0597a967532b0 to your computer and use it in GitHub Desktop.
Save robmccoll/edbd0f80ea2c5d7851b0597a967532b0 to your computer and use it in GitHub Desktop.
Go language idea: String alias types

Improved Go string alias types? (needs better name)

What?

func Authenticate(user string:UserID, password string:UserPassword) (string:JWT, error) {
  // ...
}

type User struct {
  UserID   string:UserID
  Password string:UserPassword
}

var u User
alias(u.UserID) == "UserID" // is true

var id string
id = u.UserID // fine
u.UserID = id // fine
alias(id) == "UserID" // is true
Authenticate(id, u.UserID) // fine

var machineID string:MachineID
machineID = id // panic
id = machineID // fine
alias(id) == "MachineID" // is true
Authenticate(machineID, u.UserID) // compile time error
Authenticate(id, u.UserID) // panic

id = "test"
u.UserID = "test"
machineID = "test"
id == u.UserID // true
id == machineID // true
u.UserID == machineID // false
u.UserID == string:UserID(machineID) // true

How?

typedef struct {
  char *buf;
  len  uint32_t;
  cap  uint32_t;

  // Probably intern these and do pointer comparisons for performance
  string * alias;
} string;

Why?

  • String aliased types can degrade to plain strings but maintain the alias transparently. This allows for more generic use of string-based structures and functions, but without throwing out all safety guarantees.
  • When comparing strings, contents must be equal and if both have aliases, the alias must be the same.
  • When assigning string values to variables:
    • Aliases are applied when an unaliased string value is assigned to a variable that has the alias.
    • If the value has an alias it must match the alias of the variable type (or the variable must be unaliased).
  • Slicing or otherwise indexing type aliased strings produces a plain string.

Alternatives

  • How is this better than the current system of type definitions and aliases?
    • Implicit where it makes sense, explicit only where necessary.
    • Still provides some protection when cast away.
    • Easier to gradually implement in an existing code base.
  • Where is it not good?
    • Creates more opportunities for runtime errors.
    • Adds some storage overhead and overhead on operations.
  • What about non-string basic types?
    • Strings seem like the most commonly problematic type for this and are already large in storage / require pointer jumping.
    • Other types would be bloated and slowed down by a change like this more significantly as a percentage of current size / operations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment