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

Prefer simple config types over function-style options #64

Closed
iand opened this issue Jul 13, 2023 · 2 comments
Closed

Prefer simple config types over function-style options #64

iand opened this issue Jul 13, 2023 · 2 comments
Labels
kind/proposal Proposals for changes in design, code style or direction

Comments

@iand
Copy link
Contributor

iand commented Jul 13, 2023

Function-style options are used in constructors as follows

NewThing(name string, opts ...Option) *Thing

The are very commonly used (especially in IPFS libraries) but they have a number of negative traits:

  1. how to handle duplicate options, which can occur when combining lists of options from multiple sources
  2. how to handle options that have overlapping responsibilities, such as options that touch 2 or more aspects of the object
  3. how to remove an option in a configuration chain, such as when overriding options read from a config file by an option derived from a flag
  4. they are verbose to write since you need to prefix each one with the package name
  5. they clutter the documentation with many extra functions
  6. they are hard to find in documentation unless they are named with a standard pattern or grouped as constructors
  7. it's difficult to inspect the default configuration or log configuration in use

Using a Config struct is simple and avoids the problems above. The constructor signature looks like:

NewThing(name string, cfg *Config) *Thing

Passing nil is interpreted as using the default config. It's conventional to provide a DefaultConfig function that returns a non-nil Config with default values populated. Users can then override fields. It's also easy to inspect the code to determine the default config.

The Config pattern is used in some IPFS packages (go-log) and it's commonly used in the Go standard library (Conn.BeginTx, jpeg.Encode, crypto.Signer) whereas function-style options are never used.

A user of the package can create their own function-style options to build config if they wish.

@guillaumemichel
Copy link
Contributor

Agreed, it makes more sense! I was dumbly copying the same config format as in go-libp2p-kad-dht https://github.com/libp2p/go-libp2p-kad-dht/blob/master/internal/config/config.go

@iand iand moved this from Unplanned to In Progress in DHT Optimization Aug 11, 2023
@iand
Copy link
Contributor Author

iand commented Aug 11, 2023

Cool. It seems we have consensus.

@iand iand closed this as completed Aug 11, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in DHT Optimization Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/proposal Proposals for changes in design, code style or direction
Projects
Archived in project
Development

No branches or pull requests

2 participants