CLI Embedding Proposal
Thanks, that makes sense to me. I've rendered your suggested changes.
@Kylebrown9 Thanks for presenting today. I think this is a good direction overall.
However, I'm really uncomfortable with imports being both positional and named arguments by default. This has several drawbacks:
- It isn't how people expect CLIs to work in existing programs. I cannot think of a single application that has this behavior.
- Based on peoples' experience, the behavior that specifying a named argument changes the positional arguments will appear somewhat surprising. Although this is deterministic, it will be unexpected.
- Because shifting positional arguments in the presence of named arguments will produce unexpected behavior, it will also potentially produce insecure or destructive behavior.
I propose instead the following:
- Imports may be either named or positional; not both.
- Imports are automatically treated as named arguments.
- Developers may use an annotation to mark an import as a positional argument.
This does something useful by default and produces no unexpected behavior.
That concern makes sense to me! So then agreed to saying that, by default, all imports are named and you can't pass them positionally from the CLI; you have to opt-in to allowing an import to be supplied positionally with a CLI annotation.
Mirroring my comment above regarding short/long, one property that I think is desirable is: if you can invoke a component successfully from the CLI without the CLI annotations, adding the CLI annotations shouldn't break you; it should only add new available syntax. This seems valuable because it allows you to (1) add CLI annotations to any existing component without worrying that you're breaking someone, and (2) invoke a component from the CLI after looking at the component's type in a type-viewer tool/UI that doesn't understand the CLI annotations (i.e., you should be able to ignore the CLI annotations). Based on this desired property, I'd propose that, when you opt-in to positional syntax, that doesn't disallow you from using the named syntax. My expectation here is that the CLI Embedding can define what constitutes a valid combination of named/positional CLI arguments in an unsurprising and safe manner similar to Python. Does that make sense?
I'm in agreement with @npmccallum, the combination of positional-or-named arguments and optional arguments creates a situation where it very easy to accidentally bind a positionally passed value to the wrong argument. In the interest of footgun non-proliferation, I'm in favor of going with things being named-only by default.
@lukewagner to make sure I understand you correctly. Are you just asking that when users specify some arguments that are positional they are still able to use other arguments that are named? which is distinct from allowing you to opt into arguments which are both. If so, I'm happy to agree, that is my intention.
Not quite: I'm suggesting that, when you opt-in to positional for a particular import (via an annotation), that doesn't disable the ability to name that same particular import. The idea being that annotations should only allow additional syntax, not disable previously-working (before the annotation) syntax.
Returning to this with the benefit of seeing how everything else has developed in the meantime: a different way to think about creating a "CLI Embedding" is to consider Bash to be just another programming language that binds to WIT, like JS, Python, Go, Rust, etc. From this perspective, there doesn't need to be a special "CLI Embedding" in the Component Model spec but, rather, Bash toolchain support which can be built separately as with all other languages. A neat consequence of this switch in perspective is that, just like there is both jco transpile and jco componentize (i.e., components-in-a-native-JS-runtime and JS-in-components) which implement the same bindings in two different directions, you could also imagine componentizing Bash (which actually sounds pretty cool).
Based on that understanding, maybe we don't need to develop this idea here, but in some other toolchain repo (which we could link to from here, if anyone starts working on it).
That makes sense to me. I'll shelve this PR and we can treat this as just another host which doesn't require any specification support.