BCL Preliminary Ideas
Very preliminary thinking about the syntax and configuration of my new command language BCL. Not design! yet.
Concepts
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:
net
ip
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).
However,
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?
Abstractions
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)
cron
job (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.
Implementation
Python
Syntax
Commands
A command looks like: noun verb modifiers
, so file delete
<file>
or url fetch
<address>
You can replace the noun constant with a specific instance of that kind, so <file>
delete
, <address>
fetch
or <file>
copy
<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.
Standard nouns
All the things.
Noun | Subtypes | Represents |
---|---|---|
file | ||
image, PDF, spreadsheet | ||
spreadsheet | can be duck-typed with a database | |
database | ||
folder | ||
device | ||
job | Deliberately fuzzy things up. Could mean a suspended/background process, OS proces, cron job, systemctl process. |
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
Path | Noun | Note |
---|---|---|
~/readme.txt | file | |
~/.config/ | folder | Test mode bits |
/dev/sda | device, (specifically, disk?) | Test mode bits |
~/cute_cats.gif | image | based on canonic file types(?) |
Standard verbs
Verb | Note |
---|---|
Create, New | would like this to have a -like _ |
Delete | |
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 |
Read | Extract content |
Write | Replace content |
Append | Date at end of existing content |
Specialized ones | |
Protect, Secure | for setting ACLs |
Options / arguments
Shell integration
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
Configuration
-
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? ↩︎