Instead of dealing with a filesystem and i/o and string literals with encoding and quoting and unquoting and all that, let's delegate to a git repo for storage and functional purity and to the editor for text manipulation and display.
Instead of string literals let's have what you might call "git literals" that are three-tuples of hash, start, offset. Maybe use a special quote?
{ad166bb74e00d18135db4a12cee74dcbe2e57a34 0 23}
Or just a regular list with a weird symbol?
[#ad166bb74e00d18135db4a12cee74dcbe2e57a34 0 23]
In any event...
How do you get them? By selecting text in the GUI and using a copy-to-stack command, eh?
The hash is a git object hash and the start and offset are in bytes (I guess? Maybe have a special UTF-8 version where they count code points or whatever?)
They represent a list of bytes (integers from 0-255) or maybe larger numbers if we have UTF-8?
There would be a whole batch of commands that work on them, like concat, let's represent that by ``++`` for now:
{#a... 0 len_a} {#b 0 len_b} ++ ------------------------------------- {#c... 0 (len_a + len_b)}
Instead of some sort of POSIX-style I/O interface have commands that work "over" these pseudo-lists.
A filesystem is an unbounded always-changing abstraction. The name of a file has no intrinsic relation with its contents, which can change over time. Most Functional languages either use "impure" constructs or IO monads or other constructs to deal with the unsuitability of FS for FP.
Let's just ignore all that and postulate a Git repo as a kind of "data oracle" that provides the runtime with the data specified by the literal.
One advantage is that you have the size of the data right there to guide optimization level.
One disadvantage is that strings less than forty-seven chars are shorter than their representation! (Not accounting for quote marks.)
{ad166bb74e00d18135db4a12cee74dcbe2e57a34 0 46} 01234567890123456789012345678901234567890123456789 ^ ^ ^ ^ ^ 0 1 2 3 4
If they are *much* shorter than that you can just use a list literal.