Very preliminary thinking about the syntax and configuration of my new command language BCL. Not design! yet.
Need an abstract syntax notation to talk about this, not BNF.
constant – literal
<placeholder> – named placeholder. Name is suggestive of the type or purpose of the placeholder.
Noun-verb vs verb-noun
Many (and common) commands are verb first:
cp <from> <to> rm <thing> sudo <command>
More specialized commands are often noun first:
Powershell is just always verb first. The verb defines the set of classes that it can act upon, and a complementary verb can have an independent set. E.g, ‘New-’ only applies to objects (I think), but ‘Delete-’ applies to files and objects.
I’m considering noun-first: scope the domain to an object then list the methods on it. Probably a habit from OOP, but maybe easier in practice.
I think verb first doesn’t scale. If you type
get-<tab>, the list of objects that can be gotten is huge. OTOH, if you type
file <tab>, the list of verbs is small (though there will be a long list of nouns to choose).
cp <from> <to>
will die a hard death. At least for files, I need to find a way to make this work.
I don’t want to get to bogged down in calculating the “whichness of what” 1, so the noun-verb combination should be “natural language” and should allow for linguistic redundancy.
Synonyms should work: “folder” == “container”; generalizing should work: “device” works for an explicitly “disk” object. But there will be some place where we have to draw fiddly distinctions: maybe “list” is different from “enumerate” when applied to a device?
Having to name all god’s creatures means some close calls. How many of these OS constructs should noun job refer to?
- process suspended in shell (numbered 1..n)
- OS process (PID nnn)
cronjob (how to name it?)
- startup process via all the many startup process managers
- batch job (running on some other server)
All can be suspended. Most can be started and stopped. Most can be configured. Seems like just one ‘job’ to me. But ‘stop’ means different command line tool under the covers when applied to
cron job (edit a config file) than to OS process (
kill). How to know which tool to use? Try this: depend on the syntax of the path spec for the noun. The path or address may include a protocol or other namespace hint as well as the pattern to provide a clue.
((need a better example of this, cron/edit a file is far-fetched)).
Depth of detail
Generally, I’m going to have to look at the man page for a tool and write some configuration and help wrapper for it, then merge this into a mega parse tree.
The further I go into system startup and network configuration, the more unique and specialized nouns and verbs I’m going to have to name, add to list of alternatives for tab completion, etc. How to know where to stop?
- If the tool is configured primarily/exclusively through a config file, let it be.
- If there’s a man page for a command tool, it’s a candidate.
I’m definitely thinking of adding some scripts or tools to flesh out some additional nouns, though: e.g ‘background-job’ or just ‘job’ that can be scheduled, stopped, started. Would apply to
cron but also to
systemctl (breaks the rule).
Extensibility / plugins
Right now, it seems like implementing ‘website’ based on
nginx configuration hacking is way out there.
But it should be easy for someone to package up support for nginx and distribute it as a plugin, maybe part of the nginx package someday. Show what’s involved in that?
I don’t know right now, let’s code up some mainline examples and see what it takes.
A command looks like:
noun verb modifiers, so
You can replace the noun constant with a specific instance of that kind, so
<new path> all work.
Special case, because
cp <from> <to> is so well-engrained in everybody’s fingertips, if we can parse
<from> as a file, we will figure out some way to accept
cp as the verb.
All the things.
|image, PDF, spreadsheet|
|spreadsheet||can be duck-typed with a database|
|job||Deliberately fuzzy things up. Could mean a suspended/background process, OS proces,
In unix, many kinds of objects exist in the file system, so we’ll have to coerce the path to get a type 2, e.g
|~/.config/||folder||Test mode bits|
|/dev/sda||device, (specifically, disk?)||Test mode bits|
|~/cute_cats.gif||image||based on canonic file types(?)|
|Create, New||would like this to have a
|Copy||Semantics for file includes cloning attributes, but that doesn’t apply to everything|
|Show||properties and attributes. ? in what format?|
|Set, Configure||same format as above|
|Update||Should change content. Not sure it’s specific enough for general use|
|Append||Date at end of existing content|
|Protect, Secure||for setting ACLs|
Options / arguments
BCL is intended to be invoked by some shell, so it must play nice with a shell. If I want to enhance pipeline, redirection or globbing, this creates ambiguity or extra escaping. I don’t have a clean solution, so for now, punt.
But how? Is BCL a line-getter that runs before the shell, or more like a command line tool that shell invokes and expects a return value from? … But the whole BCL line should be processed by BCL and the result handed to the shell. But there’s ambiguity over globbing, pipes and redirection characters, which should be processed by BCL. I want to add some value to these but do not want to invent yet more escapes or metacharacters so it all just works. Decide on this later.
For now, these features are planned:
- return code from last program returned to shell
Heinlein? or a general dis on Philosophy? ↩︎
This works for existing files, but what about new nodes? ↩︎
Everybody starts with a simple intent: use simple, standard verbs across all kinds of objects. But it gets messy when somebody implements some new kind of object and the semantics of the standard verbs don’t seem to apply (especially to the implementor, who is acutely aware of the details). How do we finesse this? ↩︎