<- Back to garden entrance

Reading the oils blog currently, and there's a lot of cool stuff about shell design there.

I thought i'd make a plant here to write down some ideas i want to keep in mind for my own shell.

For context, i've been thinking i want to make a shell that focuses on data manipulation in a very FP way. i think i want | (pipe) to be just function composition and/or function application (not sure yet).

The blocks concept is very interesting and nice looking. I like that it lets you make an awk-like DSL just like that. Especially since my initial idea for all this was inspired by awk. I'm thinking that YSH's "blocks" will be lambdas in my shell. I think i also want to call it "lambda shell". But i'm not sure, because it sounds like it'd be hard to refer to and search. "Lambda has lambdas" isn't the most understandable sentence.

More flexible command declarations

Anyway, the try example got me thinking. It would be nice if you could just specify a function that let you write stuff like try {} catch {}. Where catch is a subcommand, but it has to come after one positional argument. As far as i know, this isn't really possible in nushell, because you can define subcommands like def "command subcommand", and then have that take positional arguments, but you can't make certain subcommands do certain things based on positional arguments.

this is starting to look like groovy

I'm also thinking about what these blocks would take as input, and what they actually are. It's starting to look a lot like groovy and its closures. They take implicit arguments (not sure i wanna go there). But if we think about the awk-like example, we do need an input somewhere:

when (weight > 10) {  # weight needs to mean something here
	setvar x += weight  # and here!
}

Maybe each "closure" can take in one parameter, which can be denoted $in, or maybe just $. when would be responsible for passing this in, and then you could access properties on it. The example would become something like:

when {$.weight > 10} {
  x += $.weight
}

I've used curly braces for the condition too, because i imagine that's how you'll construct a lambda. And if you don't declare it with arguments, it can take a $ which is the argument. I think this is nice for a shell, because you'll be writing snippets/oneliners that you don't need to maintain, so it's nice to not need to give the input some almost-meaningless name, like when looping or filtering something.

I also like the concept of declaring data using YSH syntax. It seems to be pretty central in the idea of making these DSLs. I might want something like it. But i'm also thinking: is it too much? I think i'm afraid to add for example an awk-like DSL to my language, because it's too specific, maybe. And it means the language grows with a potentially weird feature. But is it any better to have a big "code as data" system which lets users write their own DSLs (and allows me to bundle some, like this awk DSL)? I feel like if it's not done correctly, it can be a huge mistake to introduce a super flexible system that ends up just creating a huge mess. I feel like that's maybe where groovy+gradle has ended up. I don't know what exactly is happening semantically when i write my mc mod dependencies. It's been abstracted into some DSL i don't completely understand, and that nobody teaches how works. You're just expected to write the things how the examples tell you to, without gaining an understanding of how gradle/groovy actually reads and interprets it under the hood. I think that's something i want to avoid, and need to be careful about.

Indentation sensitivity

I feel like this does slightly bring indentation sensitivity into question. It's something i feel like would be a bad idea to have for a shell language, but maybe i'm wrong about that. Maybe i just don't want to parse a syntax-dependent grammar. But, i would like to be able to specify blocks like:

command
 { block 1 }
 { block 2 }
new command  # This is understood as not related to the first command

It's very practical! And in general, it would be nice to be able to spread command arguments over multiple lines without needing backslashes. Gah. maybe indentation sensitive is the way.

When do things get evaluated

This is something i've also started thinking about, which might be tricky. Or maybe not, i don't know.