This boils down to the fact that you can’t specify multiple lines of grammar in the same rule head. Slash notation only works for individual words. That means you have to define several rules, and then somehow redirect them to the same piece of code (to avoid having several copies of the same response text in the source code). In general, you could use a helper predicate for that—but if you’re going to identify that text with the name of a helper predicate, why couldn’t you identify it with the name of an action?
The benefit of using the normal understand-mechanism is that you can hook into existing actions (“turn on pickup”), and you can mark the mistake as unlikely, so that “turn key” will behave as expected if a key is in scope.
(understand [drive/shift/steer/brake] as [drive])
(understand [turn key] as [drive])
(understand [drive/start | $More] as [drive])
*(understand $More as single object #pickup)
(instead of [switch on #pickup])
Your truck's not going anywhere in this condition.
Some potential changes to the language that would simplify the above:
Adding support for lists in slash-expressions, to allow e.g. [drive/shift/steer/brake]/[turn key] in a single rule head. I’m not sure I like it. Should whitespace be allowed around the slash character? If so, it should also be allowed around slashes that separate simple values, which could make the code hard to read, because it’s not obvious if a slash on its own is a normal word (part of the predicate name) or a value separator. If whitespace is not allowed around the slash character, that could lead to very long lines of source code.
Adding support for lists as the current topic, so the programmer could write e.g.
(understand ... as *). But then, should I allow arbitrary values as the current topic? What about lists that have a variable inside them, e.g. for actions with an object? That also feels wrong.
I’ll need to mull this over, but for now I recommend the approach that I showed in the example.