Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Value() function to optional types #312

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

chirino
Copy link

@chirino chirino commented May 5, 2024

The Value() is like the Get() function except that it returns the zero value when the option is not set. This can make the optimal type easier to use in some scenarios.

The Value() is like the Get() function except that it returns the 
zero value when the option is not set.  This can make the optimal
type easier to use in some scenarios.

Signed-off-by: Hiram Chirino <[email protected]>
@edgedb-cla
Copy link

edgedb-cla bot commented May 5, 2024

All commit authors signed the Contributor License Agreement.
CLA signed

@fmoor
Copy link
Member

fmoor commented May 6, 2024

Thanks for the PR!

This can make the optimal type easier to use in some scenarios.

Can you elaborate on this?

We chose the Get() API instead of using pointers because we wanted maximal type safety. Adding this Value() method seems to largely circumvent the type safety provided by Get().

@chirino
Copy link
Author

chirino commented May 6, 2024

This is just idiomatic go. Go does not have optional types. In essence, I would not recommend fighting against the language conventions to try to add more safety.

consider this use-case: I'm writing a http handler to expose some data form EdgeDB as an API for my front end and I need to covert the edgeDB result struct to struct that will be sent as a JSON result. Using the value function this is really easy:

//  in gin request hander, we do a call to edgeDB to lookup a user by id: 
	record, _ := dbGet(c, client, id)

	type User struct {
		Id       edgedb.UUID `json:"id"`
		FullName string      `json:"full_name"`
		Picture  string      `json:"picture,omitempty"` // zero values are special!
	}

	c.JSON(http.StatusOK, User{
		Id:       record.id,
		FullName: record.fullName,
		Picture:  record.picture.Value(), // I just want the zero value when not set.
	})

Without the Value() function, the caller has to deal with more toil:

        picture, _ := record.picture.Value()
	c.JSON(http.StatusOK, User{
		Id:       record.id,
		FullName: record.fullName,
		Picture:  picture,
	})

It's quite common across the go ecosystem to use the zero values to mean something like the value not being set.

@fmoor
Copy link
Member

fmoor commented May 6, 2024

I understand where you are coming from. While it is common for the zero value to mean unset it is not a rule. I don't think we are ready to commit to this kind of change quite yet. It is easy enough to write a convenience function for this.

type Getter[T any] interface {
	Get() (T, bool)
}

func Value[T any](thing Getter[T]) T {
	v, _ := thing.Get()
	return v
}

@chirino
Copy link
Author

chirino commented Jun 12, 2024

What's the downside to adding the Value() function? It seems like having the method can make life easier for many of your users without much harm to anyone else. You guys do want to attract go developers to use your project right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants