It’s easy to love the terseness one can get out of a command-line tool with a “pass by order” convention.
For example, maybe I run something like
deploy myapp sea2 production
to deploy an application called
myapp to the second production datacenter near Seattle.
This works great, except now I need to remember the order of arguments is:
deploy [app] [datacenter] [environment].
The typical solve for this problem is introducing named arguments, so you’d end up with
deploy --app myapp --datacenter sea2 --environment production
This no longer depends on the order, because we’re explicit about which value we’re passing for each argument.
The command itself is a LOT longer though!
In : len("deploy myapp sea2 production")
In : len("deploy --app myapp --datacenter sea2 --environment production")
We can improve this a bit with short named arguments, like
deploy -a myapp -d sea2 -e production
In : len("deploy -a myapp -d sea2 -e production")
but now we still need to remember that the arguments are
e and which values they’ll correspond to.
Indeed, we might even have some code that checks that the value of
environment is either
So what if we turned that on its head?
We can use our error checking code to automagically figure out which argument value corresponds to which argument!
- you know you need N args,
- In the above example,
- each arg value
a_k has a qualifier predicate
q_k that returns true for a value
v is valid for arg
v wins (e.g.
http://b.com prefers the second)
Suppose we want a markdown link generator, which takes two args:
- a url (like
- qualifier predicate: “starts with http”
- qualifier predicate: “contains ://”
- a slug (like
- qualifier predicate:
Another nice example is if our arguments are a combination of
environment, with values like these:
c / …
sea3 / … /
ord3 / …
We can define simple predicates for the latter two:
a.startswith("sea") or a.startswith("ord")
a in ["staging", "production"]
app arg is a bit trickier, though, because the engineers might name things however they want!
The ideal case would be some internal app that maintains a list of valid applications, but failing that, we could also declare something like
# is_app(a) := not is_datacenter(a) and not is_environment(a)
return not is_datacenter(a) and not is_environment(a)
md link generator w/ alt text
like ex1, but:
One trouble we might have is a given argument value qualifying for multiple arguments.
When that happens, we can (roughly in order of increasing danger):
- blow up
- ask for resolution (ie prompt)
- assume a default value
- loop over possibilities
newer: absolutely minimal OLTP to OLAP pipeline
older: feed sequences