💾 Archived View for gemini.thegonz.net › glog › 200726-senseOfPlace.gmi captured on 2022-04-29 at 12:39:25. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2020-09-24)
-=-=-=-=-=-=-
This is a rambling design post about some recent changes to my Haskell gemini client "diohsc".
From the start, diohsc was based on a simple paradigm inherited from web browsers: you "go to" a uri, its contents are downloaded and shown to you as appropriate, and you then enter commands to e.g. pipe the data to a command or save it to a file, and enter link numbers or relative uris to go elsewhere.
So the implicit grounding metaphor is: network locations are places you go to; once there, you can look around, do things with what you find, and travel onwards to neighbouring locations. This is strongly analagous to parser interactive fiction (adventure/zork/photopia), and I find the sense of embodiment to be powerful and appropriate -- you do feel like a guest at the sites you visit, giving the correct impression that the owner of the site may be observing your presence and watching what you're doing there, and being in one place at a time avoids attention fragmentation.
But sometimes this paradigm is too limiting. This is a post about overcoming the constraints it imposes.
These limitations were first brought to my attention by experiments with streaming.
Streaming already breaks the strict "go to location, *then* look around" procedure, because now you at least want to be looking *as* you enter the location, i.e. have the response streamed to your terminal while it's downloading. But then this suggests something more general: if I can stream text to my terminal, why can't I stream audio to my music player? Why do I have to "go to" konpeito's mix tape before I can play it?
Here, I got stuck for some time on notation. How do you express "pipe foo.mp3 to the command 'mpv -'" in compact form? We could take the parser fiction approach and actually use the preposition 'to', but that's horrible. Or we could have the command be "pipe URI COMMAND [ARGS]", but then what about the common case of wanting to pipe what's at the current location?
My eventual solution, which I think is both intrinsically correct and non-obvious enough that I'm bothering to write this post, is to put the URI *before* the pipe command: "[URI] pipe COMMAND [ARGS]" (or more suggestively: "[URI] | COMMAND [ARGS]") with an empty URI meaning "current location".
Then this applies not just to the 'pipe' command. Locations become nouns to be placed before the verb: "[URI] COMMAND [ARGS]". Pushing further, everything falls into place. "URI" can mean not just an explicit absolute uri, but any notation specifying a location -- a relative uri, a link number, a mark ("'geddit"), a history item ("^" for previous, "^5" for 5 back, etc), and even more advanced things like "^3.2" for link 2 from the history item 3 back. The old "go" and "relativego" commands disappear - enter a bare location to go there. Same for "up", "back", and "forward", which are replaced by "..", "^", and "^-1" (though in fact I'm keeping "back" and "forward" as friendly synonyms).
More location notation will be implemented in the future. In particular for queues, a feature analogous to AV98's "tour" command, which is next on my TODO list.
There's more I could say on the technical side, in particular on my struggles to control the (rightly feared) magical power of lazy IO to handle streams without introducing complexity throughout the codebase, but I don't think that belongs in this post.
3 | mpv - : request link 3 and pipe the stream to the command 'mpv -' ^4 > blah : save data from history. / m root : mark the root of the current site as 'root / id asdf : use client certificate identity "asdf" for whole of current site ? : start new query at current uri
Treating network locations as objects and breaking natural language conventions leads to a compact and regular command line interface.
Users of diohsc (yes, both of us) will have a little relearning to do, but it should be worth it.