First Embed, and Optional Arguments
Came up with a name: Universal Control Language: UCL. See, you have TCL;
but what if instead of being used for tools, it can be more universal?
Sounds so much more… universal, am I right? 😀
Yeah, okay.
It's not a great name. But it'll do for now.
Anyway, I've
started integrating this language with the admin tool I'm using at work.
This tool I use is the impetus for this whole endeavour. Up until now,
this tool was just a standard CLI command usable from the shell. But
it's not uncommon for me to have to invoke the tool multiple times in
quick succession, and each time I invoke it, it needs to connect to
backend systems, which can take a few seconds. Hence the reason why I'm
converting it into a REPL.
Anyway, I added UCL to the tool,
along with a readline
library, and wow, did it feel good to use. So much better than the
simple quote-aware string splitter I'd would've used. And just after I
added it, I got a flurry of requests from my boss to gather some
information, and although the language couldn't quite handle the task
due to missing or unfinished features, I can definitely see the
potential there.
I'm trying my best to only use what will
eventually be the public API to add the tool-specific bindings. The
biggest issue is that these "user bindings" (i.e. the non-builtins)
desperately need support for producing and consuming streams. They're
currently producing Go slices, which are being passed around as opaque
"proxy objects", but these can't be piped into other commands to, say,
filter or map. Some other major limitations:
- No commands to actually filter or map. In fact, the whole standard library needs to be built out.
- No ability to get fields from hashes or lists, including proxy objects which can act as lists or hashes.
One last thing that would be nice is the ability to define optional arguments. I actually started work on that last night, seeing that it's relatively easy to build. I'm opting for a style that looks like the switches you'd find on the command line, with option names starting with dashes:
join "a" "b" -separator "," -reverse --> b, a
Each option can have zero or more arguments, and boolean options can be
represented as just having the switch. This does mean that they'd have
to come after the positional arguments, but I think I can live with
that. Oh, and no syntactic sugar for single-character options: each
option must be separated by whitespace (the grammar actually treats them
as identifiers). In fact, I'd like to discourage the use of
single-character option names for these: I prefer the clarity that comes
from having the name written out in full (that said, I wouldn't rule out
support for aliases). This eliminates the need for double dashes, to
distinguish long option names from a cluster of single-character
options, so only the single dash will be used.
I'll talk more
about how the Go bindings look later, after I've used them a little more
and they're a little more refined.