Description
As we develop common modules in: https://github.com/openllb/modules
We want to expose as many knobs to ensure that it is reusable. However, at the same time we want to limit the number of required arguments so that you can invoke the module without being exposed to the full spectrum of options.
There's two approaches I've been thinking about:
- Optional arguments
- Option signatures
Optional arguments
Starting with some implementations from some languages:
# Named arguments in ruby
def test(var1: "var1", var2: "var2", var3: "var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok => 1111 2222 var3-new
# Default values for arguments in ruby
def test(var1="var1", var2="var2", var3="var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok but ... {:var3=>"var3-new", :var1=>1111, :var2=>2222} var2 var3
or python
optional arguments
def info(object, spacing=10, collapse=1):
# ...
info(odbchelper)
info(odbchelper, 12)
info(odbchelper, collapse=0)
info(spacing=15, object=odbchelper)
The key features extracted from the examples is:
- Positional arguments strictly before named arguments
- Named arguments can be in any order
- Values can be assigned to arguments even if they don't have default values set
In HLB, this may look like:
fs foo(string first) {
# ...
}
fs bar(string first, string second="world") {
# ...
}
group default() {
foo "hello"
foo first="hello"
bar "hello"
bar second="world" first="hello"
}
Option signatures
Currently, builtin functions like run
can take options that add optional behavior to a function. And you can define functions that wrap these builtin options too:
option::run commonOptions() {
env "key" "value"
dir "/src"
}
fs default() {
image "alpine"
run "echo foo" with commonOptions
}
User defined functions cannot have options, which makes for a odd experience. Here's some explorations into how we can make this work:
Idea 1
fs foo(string requiredArg) {
image baseImage="alpine:3.9"
}
fs default() {
foo "hello" with option {
baseImage "alpine:3.9"
}
}
Idea 2
# Looking awful like optional arguments
fs foo(string requiredArg) optional (string baseImage="alpine:3.9") {
image baseImage
}
fs default() {
foo "hello" with option {
baseImage "alpine:3.9"
}
}
Activity