elves / elvish

Powerful scripting language & versatile interactive shell
https://elv.sh/
BSD 2-Clause "Simplified" License
5.65k stars 299 forks source link

Indexing into a list of maps #1819

Open iandol opened 4 months ago

iandol commented 4 months ago

What new feature should Elvish have?

Given this variable:

var x = [[&name=cffi &version=1.16.0] [&name=pip &version=24.0] [&name=pycparser &version=2.21] [&name=pymunk &version=6.8.0] [&name=setuptools &version=70.0.0]]

I want to interactively extract out the names of each map item. Probably due to my use of MATLAB, I intuitively wanted to use the list slice to select all items then index the name:

var y = $x[..][name]

This syntax is compact and would enable us to quickly get the values out. The elvish way currently is longer:

var y = [(each {|i| put $i[name] } $x)]

I asked on the forum, and Krader warned of the slippery slope of this sort of "syntactic sugar". So these sorts of shortcuts do make the language easier to use when using them, but also more complex. Does the benefits of easier mixed list/map use ( I think it is a common pattern to have a list of maps), outweigh the added complexity?

Output of "elvish -version"

0.21.0-dev.0.20240515223629-06979efb9a2a+official

Code of Conduct

xiaq commented 3 months ago

The indexing expression allows multiple values as the indexee, so you can use:

var y = [(all $x)[name]]
var y = [$@x[name]]

I figure these are not too bad?


Tangential and I may have mentioned it elsewhere, an idea I've been playing with is to support a special @ index that evaluates to all the values - so $a[@] will be equivalent to (all $a) or $@a. This will supersede the current $@a syntax and you'd write this as:

var y = [$x[@][name]]

The main motivation is that constructs like $@a[foo] can feel ambiguous: it is equivalent to (all $a)[foo] (which is useful in the context of this issue) but the programmer may have intended (all $a[foo]). Moving the @ to the suffix position eliminates this ambiguity and allows you to write both $a[@][foo] and $a[foo][@].

iandol commented 3 months ago

@xiaq I figure these are not too bad?

Ok these are fine, I wonder if there is a good place to put them as examples somewhere in the docs. When I read language.html#indexing, your solution didn't jump out at me (while technically it is shown, just not from the context of a stored map variable).