Functional options: https://gist.github.com/travisjeffery/8265ca411735f638db80e2e34bdbd3ae In real world we need to validate input. This functional options kills global namespace. Take a look my average config: ```go import ( "domain.tld/user/log" ) // default configs const ( Host string = "127.0.0.1" // default host address Port int = 8897 // default port ) // A Config represents an average config for this comment type Config struct { Log log.Config Host string Port int } // Validate the Config values func (c *Config) Validate() (err error) { if err = c.Log.Validate(); err != nil { return } if c.Host == "" { return ErrEmptyHost } if c.Port < 0 { return ErrNegtivePort } return } // NewConfig returns default configurations func NewConfig() (c *Config) { c = new(Config) c.Log = log.NewConfig() c.Host = Host c.Port = Port return } // FromFlags obtains values from command-line flags. Call this method before `flag.Parse` and // validate the Config after that func (c *Config) FromFlags() { c.Log.FromFlags() flag.StringVar(&c.Host, "h", c.Host, "host address") flag.StringVar(&c.Port, "p", c.Port, "port") } ``` - the main problem is inventing new name for `Host` and `Port` constants How to validate configs using the functional options? ```go func Option func(c *Config) error // Host ... what I need to write here? func Host(address string) Option { if address == "" { return func(*Config) error { return ErrEmptyAddress } } return func(c *Config) (_ error) { c.Host = address return } } ``` But we also need to validate configs from flags ```go func validateHost(address string) (err error) { if address == "" { err = ErrEmptyAddress } return } func Host(address string) Option { return func(c *Config) (err error) { if err = validateHost(address); err != nil { return } c.Host = address return } } ``` Let's see global namespace ``` Host Port Config NewConfig ``` vs ``` defaultHost defaultPort validateHost validatePort Host Port Config NewConfig ``` How to deal with the `Config.Log`?