casey / just

🤖 Just a command runner
https://just.systems
Creative Commons Zero v1.0 Universal
21.44k stars 477 forks source link

Make all values lists of strings, instead of strings #2458

Open casey opened 1 week ago

casey commented 1 week ago

Just values are all strings. This is convenient, because it means that Just is effectively statically typed. It is impossible to provoke a type error.

However, it means that many desirable things are impossible:

We could add a type system, see #528. But another interesting option would be to change our single type from strings to lists of strings. This is done in rc, Plan 9s shell.

This seems crazy! Everything is a list? However, consider this: The shell, and Just, benefit from enormous simplicity because everything is a string. No type errors! No type system! We could abandon this, and add a type system, but another path is to make the one type we do have more powerful.

All current values, instead of being strings, would be lists containing single strings. When used in interpolations, or as arguments to / and +, an list of a single string would behave in exactly the same way as a string does now, so this would be a backwards compatible change.

This would allow the following nice things:

The main downside, I think, is that it is very unfamiliar and counter-intuitive. Users are used to shell-like languages, including make and just, where everything is a string. Everything is a list of strings is very weird. rc implements and makes a compelling case for lists of lists being the single type, but it's unfamiliar and mostly forgotten.

Open questions:

neunenak commented 1 week ago

Open questions:

* Should we call them lists or arrays?

I personally prefer the terminology list, but it doesn't really matter.

* Should we go even further and make the only type associative arrays? Associative arrays are more powerful, but emulating lists with associative arrays is problematic, and lists are a popular type. Plus we're really going down the dynamic language path at that point, since property access can fail.

Associative arrays are useful, but they can be emulated with a list of 2-lists representing keys and values. On the other hand, I don't think that treating a list as an implicit associative array with natural number keys, Javascript-style, is necessarily a problem. If there's any mechanism for indexing into a list with a natural number, then that has the possibility of failing even if there's no notion of an associative array.

gyreas commented 2 days ago

hmmm...

I still think clear separation between list and string is the way to go. Essentially introducing an additional type: list, which maintain the static-typing of Just. I think it's more intuitive than ditching singular strings.

casey commented 2 days ago

I still think clear separation between list and string is the way to go. Essentially introducing an additional type: list, which maintain the static-typing of Just. I think it's more intuitive than ditching singular strings.

Adding two types, lists and strings, would mean that just would either become dynamically typed, and have type errors when you tried to use a list where a string was necessary, or vice versa; or we would have to add a static type system, which would be a huge undertaking.

gyreas commented 2 days ago

In a way, though, you still be creating two types since a list is a composite type; it needs elements to make sense (or not). As for dynamic typing, like I mention below, singular strings will convert to singular lists. This conversion can happen somewhere between parsing and evaluation. Besides, isn't Just an interpreter of commands, dynamic typing shouldn't come as a shock to it.

Re-reading Drew response to another hacker's experiment on whitespaces in shell here, he mentions that the key ingredient is adding list of strings (alongside strings).

I think for Just, we should treat strings like a list with one element. Citing your example: ["/", "/usr"] / "bin", you already instinctively feel that "bin" should be used like that rather than ["/", "/usr"] / ["bin"].

PS: I haven't looked at Just source in a long while, maybe out of touch with this reality. Lemme know